サーチ…


前書き

AndroidのロケーションAPIは、ユーザーの場所を特定したり、ユーザーがいつ一般エリアを離れたかを通知したり(ジオフェンシング)、ユーザーの行動(歩行、走行、運転など)を解釈するなど、様々な目的でさまざまなアプリケーションで使用されます。

しかし、Android Location APIはユーザーの場所を取得する唯一の手段ではありません。以下は、AndroidのLocationManagerと他の一般的な位置情報ライブラリの使い方の例です。

備考

Androidでロケーション認識アプリを構築するには、次の2つの方法があります。

LocationManager

長所

  • より詳細な制御
  • すべてのデバイスで利用可能
  • Androidフレームワークの一部

短所

  • 適切に管理されないと、バッテリの放電が問題になります
  • デバイスが場所を見つけることができない場合(例えば、建物内の劣悪なGPS)には、ロケーションプロバイダを切り替えるロジックが必要です。

特徴

  • NMEAリスナー
  • GPSステータスリスナー
  • プロバイダのステータスの変更を聞く(例:GPSがユーザーによってオフになっている)
  • ロケーションソースを選択するプロバイダのリスト

プロバイダー

GPS

  • 必要な権限:
  • 精度:10m〜100m
  • 電源要件:HIGH
  • 在庫状況:全世界(空をはっきりと見える)
  • 注意
    • 位置更新は、通常、1秒に1回の頻度で行われますが、GPSを使用していない状態でA-GPSが利用できない場合は、場所を受信するまでに数分かかります。
    • 空がはっきりと見えなくなった場合、GPSポイントは非常によく集まらず(ロケーションポイントが「ジャンプ」)、「 アーバンキャニオン 」効果のために特定のエリアで誤解を招く可能性があります。

ネットワーク

  • 必要な権限:
  • 精度:100m〜1000m +
  • 電源要件:LOW - MEDIUM
  • 可用性:セルタワーまたは無線LAN信号の範囲内
  • ノート:
    • 場所の更新はGPSよりも頻繁に発生します
    • 位置情報の更新は、一般的にうまくいっていません(ロケーションポイントは「ジャンプ」します)。精度はさまざまな要因(Wi-Fi信号数、信号強度、セルタワーのタイプなど)

受動的

  • 必要な権限:
  • 精度:10m〜1000m +
  • 電源要件:なし
  • 利用可能:他のアプリがGPSまたはネットワークのいずれかから位置情報を受信した場合のみ
  • ノート:
    • あなたに継続的な更新を与えるためにこれに頼らないでください。これは、ロケーション要求を行う他のアプリに受動的に耳を傾け、それらのロケーションを戻します。
    • FusedLocationProviderApiで生成されたポイントを返しません。生成されたポイントを生成するために使用された基礎的なポイントのみを返します。

FusedLocationProviderApi

長所

  • バッテリーの消耗を「すぐに」提供
  • 悪いGPSをうまく扱う
  • より定期的に更新を取得する

短所

  • GPSによるより細かい制御
  • すべての端末または一部の国で利用できない可能性があります
  • サードパーティのライブラリ依存関係が必要

特徴

  • 最適なバッター・セービングのためのロケーション・プロバイダの適切な管理
  • 典型的には、ネットワークロケーションプロバイダ
  • より頻繁なライブラリの更新により、より多くの改善が可能
  • 使用するプロバイダのタイプを指定する必要はありません

LocationRequestの優先レベル

PRIORITY_HIGH_ACCURACY

  • 必要な権限:
  • 精度:10m〜100m
  • 電源要件:HIGH
  • 可用性:Google Playサービスが利用できるところはどこにでもあります。
  • ノート:
    • ACCESS_FINE_LOCATIONが使用されていない場合は、ロケーション更新を生成するためにGPSは使用されませんが、正しい条件ではかなり正確なポイントが見つかるでしょう。
    • ACCESS_FINE_LOCATIONが使用されている場合、環境条件が与えられたときにデバイスを現在どのように正確に追跡できるかに応じて、GPSを使用して位置点を生成することができます。
    • これは、他の設定よりも正確な位置更新を報告するかもしれませんが、それはまだ " アーバンキャニオン "効果になりがちです。

PRIORITY_BALANCED_POWER_ACCURACY

  • 必要な権限:
  • 精度: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. マニフェストを確認してください!

    最も一般的な問題の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


  1. (Android 6+用) ランタイムのアクセス許可を確認してください

    確認し、許可をリクエストしてください!権限が与えられていない場合は、クラッシュするか、すべての例外をキャッチしている場合は悪化します。何も表示されません。ユーザーがアプリの開始時にあなたに許可を与えても問題はありません。常にすべての通話にアクセス権があるかどうかを確認してください。ユーザーは簡単に設定に行き、取り消すことができます。


  1. コードを再確認してください!

    あなたは正しいリスナーを通過していると確信していますか? BroadcastReceiverまたはIntentServiceをマニフェストに追加しましたか?あなたは使用しているPendingIntent.getService()BroadcastReceiverクラス、またはgetBroadcast()IntentServiceクラス?あなたはリクエストした直後にあなたのリスナーをあなたのコードのどこかに登録解除していないと確信していますか?


  1. デバイスの設定を確認してください!

    明らかに、位置情報サービスがオンになっていることを確認してください。

    ここに画像の説明を入力

    ネットワークサービスを使用している場合は、「常にスキャン可能」を有効にしましたか?あなたの位置モードを「最高」(「高精度」)または「バッテリー節約」(「ネットワークのみ」)に設定していますか?

    ここに画像の説明を入力

    GPSを使用している場合、ロケーションモードで「ベスト」(「高精度」)または「デバイスのみ」をオンにしましたか?

    ここに画像の説明を入力


  1. コードを再確認してください!

    はい、これはここに2回あります。あなたが使用してみましたLocationListenerの代わりに、 PendingIntent 、またはその逆に、あなたが実際に実装確保するためLocationManager正しく?アクティビティまたはサービスのライフサイクルの一部で、場所のリクエストが削除されていないことを確認していますか?


  1. あなたの周辺をチェックしてください!

    サンフランシスコの真ん中の建物の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();
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow