#FusedLoacationProviderApiで位置情報を取得してGoogle Location Web ApiでJsonを取る
Activityに処理の起点を実装
位置情報を取得できたら
https://maps.googleapis.com/maps/api/place/search/json
をコールして周辺のスポットを取得する
jsonの中身をダイアログに表示。
以上のサンプルです。
FusedLoacationProviderApiのリスナー実装でソースの見通しがわかりづらくなるので、
別クラスに分離しました。
##Acitivityの実装
メンバー変数の定義
public class MainActivity extends AppCompatActivity {
int PLACE_PICKER_REQUEST = 1;
private final int REQUEST_PERMISSION = 10;
private Handler mHandler;
private OneShotLocationManager mLocationManager;
private String mJsonData = "";
onCreateでの処理
(前略)
mHandler = new Handler();
mLocationManager = new OneShotLocationManager(getApplicationContext()) {
@Override
public void onStopApi(int lastResponseCode) {
if(lastResponseCode != OneShotLocationManager.RES_SUCCESS)
if (mLocationManager.getLocation() == null){
return;
}
//通信スレッド生成
(new Thread(new Runnable() {
@Override
public void run() {
Location location = mLocationManager.getLocation();
if(location == null){
return;
}
double lat = location.getLatitude();
double lng = location.getLongitude();
StringBuilder urlStrBuilder = new StringBuilder("https://maps.googleapis.com/maps/api/place/search/json");
urlStrBuilder.append("?location=" + lat + "," + lng);
urlStrBuilder.append("&sensor=true&rankby=distance&key="+getString(R.string.google_maps_key));
URL url = null;
try {
url = new URL(urlStrBuilder.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
return;
}
// APIを叩いてJSONをダウンロード
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
int bytesRead = -1;
byte[] buffer = new byte[1024];
mJsonData = "";
while ((bytesRead = inputStream.read(buffer)) != -1) {
mJsonData += new String(buffer);
}
inputStream.close();
mHandler.post(new Runnable() {
@Override
public void run() {
new AlertDialog.Builder(MainActivity.this)
.setTitle("title")
.setMessage(
mJsonData)
.setPositiveButton("OK", null)
.show();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
})).start();
}
};
//ボタン押下で位置情報を取得開始する。
Button btnPlaceApiWeb = (Button) findViewById(R.id.btn_place_web);
btnPlaceApiWeb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//パーミッションチェック
if(Build.VERSION.SDK_INT >= 23){
if(!mLocationManager.checkLocationPermission()){
requestLocationPermission();
return;
}
}
//API呼ぶ
if(OneShotLocationManager.RES_SUCCESS != mLocationManager.startApi()){
if(mLocationManager.getLastResponseCode() == OneShotLocationManager.RES_PERMISSION){
requestLocationPermission();
return;
}
}
}
});
イベントハンドリング周りとパーミッションの要求処理
// 許可を求める
private void requestLocationPermission() {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
Toast toast = Toast.makeText(this, "ロケーションを許可しないと実行できません。", Toast.LENGTH_SHORT);
toast.show();
}
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION);
}
// 結果の受け取り
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_PERMISSION) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast toast = Toast.makeText(this, "ロケーションを許可しないと実行できません。", Toast.LENGTH_SHORT);
toast.show();
}
}
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
mLocationManager.stopApi();
}
##実装するリスナー等をまとめたクラス
これをActivityに書くサンプルが多すぎてわけわからんとなるので、別クラスにまとめる
OneShotLocationManager.java
package com.example.y_hoshi.maptest.mng;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 位置情報を1度だけ取得する
* 関連のAPIのリスナーわかりやすく分離して実装したクラス
* UIスレッドでインスタンスを作る。
* Created by y_hoshi on 2016/10/28.
*/
abstract public class OneShotLocationManager implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener, LocationListener {
public static final int RES_CONNECTION_FAILD = -2;
public static final int RES_PERMISSION = -1;
public static final int RES_SUCCESS = 0;
private int lastResponseCode = 0;
public int getLastResponseCode(){return lastResponseCode;};
Context mContext;
private final int REQUEST_PERMISSION = 10;
private GoogleApiClient mGoogleApiClient;
private FusedLocationProviderApi fusedLocationProviderApi;
private LocationRequest locationRequest;
private Location location;
public Location getLocation(){return location;};
private long lastLocationTime = 0;
private Handler mHandler;
//通信が終わった時の通知用
protected abstract void onStopApi(int lastResponseCode);
public OneShotLocationManager(Context context) {
mContext = context;
mHandler = new Handler();
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(1000);
locationRequest.setFastestInterval(16);
fusedLocationProviderApi = LocationServices.FusedLocationApi;
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(mContext,android. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location currentLocation = fusedLocationProviderApi.getLastLocation(mGoogleApiClient);
if (currentLocation != null && currentLocation.getTime() > 20000) {
location = currentLocation;
String log = "onConnected ---------- \n";
log += "lat=" + String.valueOf(location.getLatitude()) + "\n";
log += "lon=" + String.valueOf(location.getLongitude()) + "\n";
log += "accuracy=" + String.valueOf(location.getAccuracy()) + "\n";
log += "altitude=" + String.valueOf(location.getAltitude()) + "\n";
log += "time=" + String.valueOf(location.getTime()) + "\n";
log += "speed=" + String.valueOf(location.getSpeed()) + "\n";
log += "bearing=" + String.valueOf(location.getBearing()) + "\n";
Log.d("location", log);
} else {
try {
fusedLocationProviderApi.requestLocationUpdates(mGoogleApiClient, locationRequest, (LocationListener) this);
Executors.newScheduledThreadPool(1).schedule(new Runnable() {
@Override
public void run() {
fusedLocationProviderApi.removeLocationUpdates(mGoogleApiClient,(LocationListener) OneShotLocationManager.this);
}
}, 60000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace();
lastResponseCode = RES_PERMISSION;
onStopApi(getLastResponseCode());
return;
}
}
if (currentLocation == null){
return;
}
lastResponseCode = RES_SUCCESS;
stopApi();
}
@Override
public void onConnectionSuspended(int i) {
Log.d("locationMng", "onConnectionSuspended------------- \n" + "i=" + i + "\n");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.d("locationMng", "onConnectionFaild------------- \n" + "errorCode=" + connectionResult.getErrorCode() + "\n");
lastResponseCode = RES_CONNECTION_FAILD;
onStopApi(lastResponseCode);
}
@Override
public void onLocationChanged(Location location) {
lastLocationTime = RES_CONNECTION_FAILD;
lastLocationTime = location.getTime() - lastLocationTime;
String log = "onLocationChanged-------------------- \n";
log += "lat=" + String.valueOf(location.getLatitude()) + "\n";
log += "lon=" + String.valueOf(location.getLongitude()) + "\n";
log += "accuracy=" + String.valueOf(location.getAccuracy()) + "\n";
log += "altitude=" + String.valueOf(location.getAltitude()) + "\n";
log += "time=" + String.valueOf(location.getTime()) + "\n";
log += "speed=" + String.valueOf(location.getSpeed()) + "\n";
log += "bearing=" + String.valueOf(location.getBearing()) + "\n";
log += "lastLocationTime= " + String.valueOf(lastLocationTime) + " msec \n";
Log.d("locationMng", log);
}
public int startApi(){
Log.d("locationMng", "start-------------");
if(!checkLocationPermission()){
lastResponseCode = RES_PERMISSION;
return lastResponseCode;
}
mGoogleApiClient.connect();
lastResponseCode = RES_SUCCESS;
return RES_SUCCESS;
}
public void stopApi(){
mGoogleApiClient.disconnect();
onStopApi(getLastResponseCode());
return;
}
/**
* 必要なパーミッションのチェックをして拒否しているならパーミッションをリクエストする
*/
public boolean checkLocationPermission() {
int permissionCheck = ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION);
//許可されていない
if (permissionCheck != PackageManager.PERMISSION_GRANTED){
return false;
}
return true;
}
}