Android
ロケーション
サーチ…
前書き
AndroidのロケーションAPIは、ユーザーの場所を特定したり、ユーザーがいつ一般エリアを離れたかを通知したり(ジオフェンシング)、ユーザーの行動(歩行、走行、運転など)を解釈するなど、様々な目的でさまざまなアプリケーションで使用されます。
しかし、Android Location APIはユーザーの場所を取得する唯一の手段ではありません。以下は、AndroidのLocationManager
と他の一般的な位置情報ライブラリの使い方の例です。
備考
Androidでロケーション認識アプリを構築するには、次の2つの方法があります。
- Androidのネイティブオープンソース
LocationManager
- Google Playサービスの一部であるGoogleの
FusedLocationProviderApi
LocationManager
長所
- より詳細な制御
- すべてのデバイスで利用可能
- Androidフレームワークの一部
短所
- 適切に管理されないと、バッテリの放電が問題になります
- デバイスが場所を見つけることができない場合(例えば、建物内の劣悪なGPS)には、ロケーションプロバイダを切り替えるロジックが必要です。
特徴
- NMEAリスナー
- GPSステータスリスナー
- プロバイダのステータスの変更を聞く(例:GPSがユーザーによってオフになっている)
- ロケーションソースを選択するプロバイダのリスト
プロバイダー
GPS
- 必要な権限:
- 精度:10m〜100m
- 電源要件:HIGH
- 在庫状況:全世界(空をはっきりと見える)
- 注意 :
ネットワーク
- 必要な権限:
- 精度:100m〜1000m +
- 電源要件:LOW - MEDIUM
- 可用性:セルタワーまたは無線LAN信号の範囲内
- ノート:
- 場所の更新はGPSよりも頻繁に発生します
- 位置情報の更新は、一般的にうまくいっていません(ロケーションポイントは「ジャンプ」します)。精度はさまざまな要因(Wi-Fi信号数、信号強度、セルタワーのタイプなど)
受動的
- 必要な権限:
- 精度:10m〜1000m +
- 電源要件:なし
- 利用可能:他のアプリがGPSまたはネットワークのいずれかから位置情報を受信した場合のみ
- ノート:
- あなたに継続的な更新を与えるためにこれに頼らないでください。これは、ロケーション要求を行う他のアプリに受動的に耳を傾け、それらのロケーションを戻します。
- FusedLocationProviderApiで生成されたポイントを返しません。生成されたポイントを生成するために使用された基礎的なポイントのみを返します。
FusedLocationProviderApi
長所
- バッテリーの消耗を「すぐに」提供
- 悪いGPSをうまく扱う
- より定期的に更新を取得する
短所
- GPSによるより細かい制御
- すべての端末または一部の国で利用できない可能性があります
- サードパーティのライブラリ依存関係が必要
特徴
- 最適なバッター・セービングのためのロケーション・プロバイダの適切な管理
- 典型的には、ネットワークロケーションプロバイダ
- より頻繁なライブラリの更新により、より多くの改善が可能
- 使用するプロバイダのタイプを指定する必要はありません
LocationRequestの優先レベル
PRIORITY_HIGH_ACCURACY
- 必要な権限:
-
ACCESS_FINE_LOCATION
より正確な場所、またはACCESS_COARSE_LOCATION
より正確でない場所
-
- 精度:10m〜100m
- 電源要件:HIGH
- 可用性:Google Playサービスが利用できるところはどこにでもあります。
- ノート:
-
ACCESS_FINE_LOCATION
が使用されていない場合は、ロケーション更新を生成するためにGPSは使用されませんが、正しい条件ではかなり正確なポイントが見つかるでしょう。 -
ACCESS_FINE_LOCATION
が使用されている場合、環境条件が与えられたときにデバイスを現在どのように正確に追跡できるかに応じて、GPSを使用して位置点を生成することができます。 - これは、他の設定よりも正確な位置更新を報告するかもしれませんが、それはまだ " アーバンキャニオン "効果になりがちです。
-
PRIORITY_BALANCED_POWER_ACCURACY
- 必要な権限:
-
ACCESS_FINE_LOCATION
より正確な場所、またはACCESS_COARSE_LOCATION
より正確でない場所
-
- 精度:100m〜1000m +
- 電源要件:MEDIUM
- 可用性:Google Playサービスが利用できるところはどこにでもあります。
- ノート:
-
PRIORITY_HIGH_ACCURACY
同じノート - 可能性は低いですが、この設定ではGPSを使用して場所を生成することがあります。
-
PRIORITY_LOW_POWER
- 必要な権限:
- 精度:100m〜1000m +
- 電源要件:低
- 可用性:Google Playサービスが利用できるところはどこにでもあります。
- ノート:
- おそらく、GPSは使用していませんが、これまでのところテストされていません。
- アップデートは一般的にあまり正確ではありません
- 一般的に場所の大幅な変化を検出するために使用されます
PRIORITY_NO_POWER
- 必要な権限:
- 精度:10m〜1000m +
- 電源要件:なし
- 可用性:Google Playサービスが利用できるところはどこにでもあります。
- ノート:
-
LocationManager
PASSIVE_PROVIDER
とほぼ同じ機能 - 受信時にGoogle Playサービスの更新を報告します
PASSIVE_PROVIDER
は、使用された基本的な位置の更新を報告します
-
トラブルシューティング
OnLocationChanged()は呼び出されません
これはAndroidの場所を取得する際の一般的な問題であると思われるため、よくある修正の簡単なチェックリストを掲載します。
マニフェストを確認してください!
最も一般的な問題の1つは、適切な権限が与えられていないことです。 GPSを使用している場合は、
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
を使用し、そうでない場合は<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
。 GoogleのFusedLocationApiにはACCESS_FINE_LOCATIONが必要ACCESS_FINE_LOCATION
。
(Android 6+用) ランタイムのアクセス許可を確認してください !
確認し、許可をリクエストしてください!権限が与えられていない場合は、クラッシュするか、すべての例外をキャッチしている場合は悪化します。何も表示されません。ユーザーがアプリの開始時にあなたに許可を与えても問題はありません。常にすべての通話にアクセス権があるかどうかを確認してください。ユーザーは簡単に設定に行き、取り消すことができます。
コードを再確認してください!
あなたは正しいリスナーを通過していると確信していますか?
BroadcastReceiver
またはIntentService
をマニフェストに追加しましたか?あなたは使用しているPendingIntent.getService()
にBroadcastReceiver
クラス、またはgetBroadcast()
にIntentService
クラス?あなたはリクエストした直後にあなたのリスナーをあなたのコードのどこかに登録解除していないと確信していますか?
デバイスの設定を確認してください!
明らかに、位置情報サービスがオンになっていることを確認してください。
ネットワークサービスを使用している場合は、「常にスキャン可能」を有効にしましたか?あなたの位置モードを「最高」(「高精度」)または「バッテリー節約」(「ネットワークのみ」)に設定していますか?
GPSを使用している場合、ロケーションモードで「ベスト」(「高精度」)または「デバイスのみ」をオンにしましたか?
コードを再確認してください!
はい、これはここに2回あります。あなたが使用してみました
LocationListener
の代わりに、PendingIntent
、またはその逆に、あなたが実際に実装確保するためLocationManager
正しく?アクティビティまたはサービスのライフサイクルの一部で、場所のリクエストが削除されていないことを確認していますか?
あなたの周辺をチェックしてください!
サンフランシスコの真ん中の建物の1階にあるGPSをテストしていますか?どこにいてもネットワークの場所をテストしていますか?あなたは、あなたのデバイスがなぜ場所を取得していないのだろうかと疑問に思う、すべての無線信号の秘密の地下バンカーで働いていますか?場所の問題のトラブルシューティングを行うときには、常に周囲を再確認してください。
場所がうまくいかない理由はそれほど明白ではないかもしれませんが、これらの難解な修正を検索する前に、この簡単なチェックリストを実行してください。
融合位置API
アクティビティw / LocationRequestを使用した例
/*
* This example is useful if you only want to receive updates in this
* activity only, and have no use for location anywhere else.
*/
public class LocationActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
.setInterval(2000) //At least once every 2 seconds
.setFastestInterval(1000); //At most once a second
}
@Override
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onResume(){
super.onResume();
//Permission check for Android 6.0+
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
}
@Override
protected void onPause(){
super.onPause();
//Permission check for Android 6.0+
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
}
@Override
protected void onStop(){
super.onStop();
mGoogleApiClient.disconnect();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
//Handle your location update code here
}
}
サービスw / PendingIntentとBroadcastReceiverを使用した例
アクティビティの例
お勧め読書: LocalBroadcastManager
/*
* This example is useful if you have many different classes that should be
* receiving location updates, but want more granular control over which ones
* listen to the updates.
*
* For example, this activity will stop getting updates when it is not visible, but a database
* class with a registered local receiver will continue to receive updates, until "stopUpdates()" is called here.
*
*/
public class ExampleActivity extends AppCompatActivity {
private InternalLocationReceiver mInternalLocationReceiver;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Create internal receiver object in this method only.
mInternalLocationReceiver = new InternalLocationReceiver(this);
}
@Override
protected void onResume(){
super.onResume();
//Register to receive updates in activity only when activity is visible
LocalBroadcastManager.getInstance(this).registerReceiver(mInternalLocationReceiver, new IntentFilter("googleLocation"));
}
@Override
protected void onPause(){
super.onPause();
//Unregister to stop receiving updates in activity when it is not visible.
//NOTE: You will still receive updates even if this activity is killed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mInternalLocationReceiver);
}
//Helper method to get updates
private void requestUpdates(){
startService(new Intent(this, LocationService.class).putExtra("request", true));
}
//Helper method to stop updates
private void stopUpdates(){
startService(new Intent(this, LocationService.class).putExtra("remove", true));
}
/*
* Internal receiver used to get location updates for this activity.
*
* This receiver and any receiver registered with LocalBroadcastManager does
* not need to be registered in the Manifest.
*
*/
private static class InternalLocationReceiver extends BroadcastReceiver{
private ExampleActivity mActivity;
InternalLocationReceiver(ExampleActivity activity){
mActivity = activity;
}
@Override
public void onReceive(Context context, Intent intent) {
final ExampleActivity activity = mActivity;
if(activity != null) {
LocationResult result = intent.getParcelableExtra("result");
//Handle location update here
}
}
}
}
位置情報サービス
注:マニフェストにこのサービスを登録することを忘れないでください!
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
@Override
public void onCreate(){
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
.setInterval(2000) //At least once every 2 seconds
.setFastestInterval(1000); //At most once a second
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
super.onStartCommand(intent, flags, startId);
//Permission check for Android 6.0+
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (intent.getBooleanExtra("request", false)) {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
} else {
mGoogleApiClient.connect();
}
}
else if(intent.getBooleanExtra("remove", false)){
stopSelf();
}
}
return START_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
if(mGoogleApiClient.isConnected()){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, getPendingIntent());
mGoogleApiClient.disconnect();
}
}
private PendingIntent getPendingIntent(){
//Example for IntentService
//return PendingIntent.getService(this, 0, new Intent(this, **YOUR_INTENT_SERVICE_CLASS_HERE**), PendingIntent.FLAG_UPDATE_CURRENT);
//Example for BroadcastReceiver
return PendingIntent.getBroadcast(this, 0, new Intent(this, LocationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
//Permission check for Android 6.0+
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
}
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
LocationReceiver
注:このレシーバーをマニフェストに登録することを忘れないでください!
public class LocationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(LocationResult.hasResult(intent)){
LocationResult locationResult = LocationResult.extractResult(intent);
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("googleLocation").putExtra("result", locationResult));
}
}
}
LocationManagerを使用したロケーション更新のリクエスト
いつものように、必要な権限があることを確認する必要があります。
public class MainActivity extends AppCompatActivity implements LocationListener{
private LocationManager mLocationManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
catch(SecurityException e){
// The app doesn't have the correct permissions
}
}
@Override
protected void onPause() {
try{
mLocationManager.removeUpdates(this);
}
catch (SecurityException e){
// The app doesn't have the correct permissions
}
super.onPause();
}
@Override
public void onLocationChanged(Location location) {
// We received a location update!
Log.i("onLocationChanged", location.toString());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
LocationManagerを使用して別のスレッドでロケーションアップデートをリクエストする
いつものように、必要な権限があることを確認する必要があります。
public class MainActivity extends AppCompatActivity implements LocationListener{
private LocationManager mLocationManager = null;
HandlerThread mLocationHandlerThread = null;
Looper mLocationHandlerLooper = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationHandlerThread = new HandlerThread("locationHandlerThread");
}
@Override
protected void onResume() {
super.onResume();
mLocationHandlerThread.start();
mLocationHandlerLooper = mLocationHandlerThread.getLooper();
try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this, mLocationHandlerLooper);
}
catch(SecurityException e){
// The app doesn't have the correct permissions
}
}
@Override
protected void onPause() {
try{
mLocationManager.removeUpdates(this);
}
catch (SecurityException e){
// The app doesn't have the correct permissions
}
mLocationHandlerLooper = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
mLocationHandlerThread.quitSafely();
else
mLocationHandlerThread.quit();
mLocationHandlerThread = null;
super.onPause();
}
@Override
public void onLocationChanged(Location location) {
// We received a location update on a separate thread!
Log.i("onLocationChanged", location.toString());
// You can verify which thread you're on by something like this:
// Log.d("Which thread?", Thread.currentThread() == Looper.getMainLooper().getThread() ? "UI Thread" : "New thread");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
ジオフェンスを登録する
私はGeoFenceObserversationService
シングルトンクラスを作成しました。
GeoFenceObserversationService.java :
public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {
protected static final String TAG = "GeoFenceObserversationService";
protected GoogleApiClient mGoogleApiClient;
protected ArrayList<Geofence> mGeofenceList;
private boolean mGeofencesAdded;
private SharedPreferences mSharedPreferences;
private static GeoFenceObserversationService mInstant;
public static GeoFenceObserversationService getInstant(){
return mInstant;
}
@Override
public void onCreate() {
super.onCreate();
mInstant = this;
mGeofenceList = new ArrayList<Geofence>();
mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);
buildGoogleApiClient();
}
@Override
public void onDestroy() {
mGoogleApiClient.disconnect();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
protected void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
}
@Override
public void onConnectionSuspended(int cause) {
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
public void addGeofences() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
populateGeofenceList();
if(!mGeofenceList.isEmpty()){
try {
LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
} catch (SecurityException securityException) {
securityException.printStackTrace();
}
}
}
public void removeGeofences() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
} catch (SecurityException securityException) {
securityException.printStackTrace();
}
}
public void onResult(Status status) {
if (status.isSuccess()) {
mGeofencesAdded = !mGeofencesAdded;
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
editor.apply();
} else {
String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
Log.i("Geofence", errorMessage);
}
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private void populateGeofenceList() {
mGeofenceList.clear();
List<GeoFencingResponce> geoFenceList = getGeofencesList;
if(geoFenceList!=null&&!geoFenceList.isEmpty()){
for (GeoFencingResponce obj : geoFenceList){
mGeofenceList.add(obj.getGeofence());
Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
}
}
}
}
AppConstant :
public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
public static final String DETECTED_GEOFENCES = "detected_geofences";
public static final String DETECTED_BEACONS = "detected_beacons";
public static String getErrorString(Context context, int errorCode) {
Resources mResources = context.getResources();
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return mResources.getString(R.string.geofence_not_available);
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return mResources.getString(R.string.geofence_too_many_geofences);
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return mResources.getString(R.string.geofence_too_many_pending_intents);
default:
return mResources.getString(R.string.unknown_geofence_error);
}
}
私はどこでサービスを始めたのですか?アプリケーションクラスから
-
startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));
ジオフェンスの登録方法
-
GeoFenceObserversationService.getInstant().addGeofences();
Geocoderを使用してロケーションからアドレスを取得する
FusedAPI
からLocation
オブジェクトを取得したら、そのオブジェクトからAddress
情報を簡単に取得できます。
private Address getCountryInfo(Location location) {
Address address = null;
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
String errorMessage;
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(),
// In this sample, get just a single address.
1);
} catch (IOException ioException) {
// Catch network or other I/O problems.
errorMessage = "IOException>>" + ioException.getMessage();
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = "IllegalArgumentException>>" + illegalArgumentException.getMessage();
}
if (addresses != null && !addresses.isEmpty()) {
address = addresses.get(0);
}
return country;
}
BroadcastReceiverでの位置情報の取得
最初に、着信ロケーションの更新を処理するBroadcastReceiverクラスを作成します。
public class LocationReceiver extends BroadcastReceiver implements Constants {
@Override
public void onReceive(Context context, Intent intent) {
if (LocationResult.hasResult(intent)) {
LocationResult locationResult = LocationResult.extractResult(intent);
Location location = locationResult.getLastLocation();
if (location != null) {
// Do something with your location
} else {
Log.d(LocationReceiver.class.getSimpleName(), "*** location object is null ***");
}
}
}
}
onConnectedコールバックでGoogleApiClientに接続すると、次のようになります。
@Override
public void onConnected(Bundle connectionHint) {
Intent backgroundIntent = new Intent(this, LocationReceiver.class);
mBackgroundPendingIntent = backgroundPendingIntent.getBroadcast(getApplicationContext(), LOCATION_REUEST_CODE, backgroundIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mFusedLocationProviderApi.requestLocationUpdates(mLocationClient, mLocationRequest, backgroundPendingIntent);
}
適切なライフサイクル・コールバックでロケーション更新インテントを削除することを忘れないでください。
@Override
public void onDestroy() {
if (servicesAvailable && mLocationClient != null) {
if (mLocationClient.isConnected()) {
fusedLocationProviderApi.removeLocationUpdates(mLocationClient, backgroundPendingIntent);
// Destroy the current location client
mLocationClient = null;
} else {
mLocationClient.unregisterConnectionCallbacks(this);
mLocationClient = null;
}
}
super.onDestroy();
}