###前提・実現したいこと
Android Studioにて、現在地を常に表示し続けるというシステムを作っています。
FusedLocationProviderApiを使って現在地を取得し、Google APIを使って現在地を地図上に表示し続けようとしています。
###発生している問題・エラーメッセージ
MapsActivityのメインクラス、現在地を取得するためのサブクラス(LocationActivity)に分けて実装しようとしています。
ですが、エミュレータ上で起動するとエラーが起こってしまい、アプリが強制終了してしまいます。
エミュレーター上のエラーメッセージ:Unfortnately, My Application has stopped.
デバッグ機能を使ってどこでエラーが起こっているのか調べてみると、サブクラスを呼び出したあとにエラーが起こっていることがわかりました。
つまり、サブクラス内での動作によってエラーが起こってしまっているということでしょう(汗)
###該当のソースコード
Java
1文字数がオーバーしてしまうため、問題のサブクラスのみ記します。 2このコードを呼び出したときにエラーが発生します。 3LocationActivity.java 4package com.example.student7.myapplication; 5 6import android.*; 7import android.content.pm.PackageManager; 8import android.location.Location; 9import android.os.Bundle; 10import android.support.v4.app.ActivityCompat; 11import android.support.v4.app.FragmentActivity; 12import android.util.Log; 13import android.view.View; 14import android.widget.Button; 15import android.widget.TextView; 16import android.widget.Toast; 17 18import com.google.android.gms.common.ConnectionResult; 19import com.google.android.gms.common.api.GoogleApiClient; 20import com.google.android.gms.location.FusedLocationProviderApi; 21import com.google.android.gms.location.LocationListener; 22import com.google.android.gms.location.LocationRequest; 23import com.google.android.gms.location.LocationServices; 24 25import java.util.concurrent.Executors; 26import java.util.concurrent.TimeUnit; 27 28/** 29 * Created by student7 on 2016/10/06. 30 */ 31public class LocationActivity extends FragmentActivity implements 32 GoogleApiClient.ConnectionCallbacks, 33 GoogleApiClient.OnConnectionFailedListener, 34 LocationListener { 35 36 // GoogleApiClient.ConnectionCallbacks をConnectionCallbacksだけにすると 37 // べつのクラスが呼ばれてGoogleApiClient.Builderでエラーになる 38 private TextView textView; 39 private String textLog = "start \n"; 40 41 // LocationClient の代わりにGoogleApiClientを使います 42 private GoogleApiClient mGoogleApiClient; 43 private boolean mResolvingError = false; 44 45 private FusedLocationProviderApi fusedLocationProviderApi; 46 47 private LocationRequest locationRequest; 48 private Location location; 49 private long lastLocationTime = 0; 50 private Common common; 51 52 @Override 53 protected void onCreate(Bundle savedInstanceState) { 54 super.onCreate(savedInstanceState); 55 setContentView(R.layout.activity_maps); 56 57 common = (Common) getApplication(); 58 59 Log.d("LocationActivity", "onCreate"); 60 61 // LocationRequest を生成して精度、インターバルを設定 62 locationRequest = LocationRequest.create(); 63 locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 64 locationRequest.setInterval(1000); 65 locationRequest.setFastestInterval(16); 66 67 fusedLocationProviderApi = LocationServices.FusedLocationApi; 68 69 mGoogleApiClient = new GoogleApiClient.Builder(this) 70 .addApi(LocationServices.API) 71 .addConnectionCallbacks(this) 72 .addOnConnectionFailedListener(this) 73 .build(); 74 75 Log.d("LocationActivity", "mGoogleApiClient"); 76 77 78 startFusedLocation(); 79 } 80 81 82 private void startFusedLocation(){ 83 Log.d("LocationActivity", "onStart"); 84 85 // Connect the client. 86 if (!mResolvingError) { 87 // Connect the client. 88 mGoogleApiClient.connect(); 89 90 } else { 91 } 92 93 } 94 95 private void stopFusedLocation(){ 96 // Disconnecting the client invalidates it. 97 mGoogleApiClient.disconnect(); 98 99 } 100 101 @Override 102 protected void onStart() { 103 super.onStart(); 104 105 } 106 107 @Override 108 protected void onStop() { 109 super.onStop(); 110 stopFusedLocation(); 111 } 112 113 114 @Override 115 public void onConnected(Bundle bundle) { 116 Log.d("LocationActivity", "onConnected"); 117 118 if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 119 return; 120 } 121 Location currentLocation = fusedLocationProviderApi.getLastLocation(mGoogleApiClient); 122 123 if (currentLocation != null && currentLocation.getTime() > 20000) { 124 location = currentLocation; 125 common.latitude += location.getLatitude(); 126 common.longitude += location.getLongitude(); 127 } else { 128 // バックグラウンドから戻ってしまうと例外が発生する場合がある 129 try { 130 // 131 fusedLocationProviderApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this); 132 // Schedule a Thread to unregister location listeners 133 Executors.newScheduledThreadPool(1).schedule(new Runnable() { 134 @Override 135 public void run() { 136 fusedLocationProviderApi.removeLocationUpdates(mGoogleApiClient, LocationActivity.this); 137 } 138 }, 60000, TimeUnit.MILLISECONDS); 139 140 textLog += "onConnected(), requestLocationUpdates \n"; 141 textView.setText(textLog); 142 143 } catch (Exception e) { 144 e.printStackTrace(); 145 Toast toast = Toast.makeText(this, "例外が発生、位置情報のPermissionを許可していますか?", Toast.LENGTH_SHORT); 146 toast.show(); 147 148 //MainActivityに戻す 149 finish(); 150 } 151 } 152 } 153 154 @Override 155 public void onLocationChanged(Location location) { 156 lastLocationTime = location.getTime() - lastLocationTime; 157 common.latitude += location.getLatitude(); 158 common.longitude += location.getLongitude(); 159 } 160 161 @Override 162 public void onConnectionSuspended(int i) { 163 } 164 165 @Override 166 public void onConnectionFailed(ConnectionResult connectionResult) { 167 168 if (mResolvingError) { 169 // Already attempting to resolve an error. 170 Log.d("", "Already attempting to resolve an error"); 171 172 return; 173 } else if (connectionResult.hasResolution()) { 174 175 } else { 176 mResolvingError = true; 177 } 178 } 179} 180
###試したこと
https://akira-watson.com/android/fusedlocationproviderapi.html
このサイトにあるソースコードを参考にして作りました。
このサイトでは、テキストとして経度緯度を表示しますが、私の場合は経度と緯度を取得して、それをGoogle APIのLatLngでMap上で現在地として表示するという形にしようと試みました。
###補足情報(言語/FW/ツール等のバージョンなど)
言語:Java
FW:4.6
Android studioバージョン:2.1.2
Google Play services:32.0.0
Google Repository:32.0.0