7415


はじめまして。  
Androidの勉強を初めて１０ヶ月の初心者です。  
Geofenceを取得するためAndroidStudioで勉強してきたのですが、情報（本、HP、サンプルコード）が少なく自己解決が難しいため、質問させていただきました。

質問：GoogleApiClientを使用したGeofenceはどのように実装するのですか？

実現したいことは、Geofence（場所は固定）に入ったらインテントを発行する。  
だけなのですが、これまでの勉強方法が本や実際に動作するサンプルコードから読み解くようにしてきたため、それらがない状態でどのようにすればいいのか？で苦労しています。  
調べたところ、これまで使用されていたライブラリがなくなりGoogleApiClientを使用することがわかり、Mapの表示、現在位置の取得まではできたのですが、どのようにGeofenceを組み込むのかがわかりません。  
アドバイスを頂ければ幸いです。

参考サイト  
<http://dev.classmethod.jp/smartphone/android/android-google-play-services-
location-api-geofencing/>  
<http://www.zionsoft.net/2014/11/google-play-services-locations-2/>  
その他多数。

サンプルコードを追加いたします。  
各サイトを参考に作ったもので、動作は地図を表示させ、現在位置を習得、カメラを移動。  
その際、ジオフェンス内ならLogに表示させることを目指したものですが、 `Geofencescheck()` の `addGeofences`
の入力で失敗してしまいます。  
また、 `onLocationChanged()` に `Geofencescheck()`
を仕込んだため、毎回、位置チェックで確認するようにしたのですが、これがジオフェンスを使用する場合の正しいのか？も判断できていません。  
この部分のアドバイスを頂ければ幸いです。

[code]

    import android.app.PendingIntent;
    import android.content.Intent;
    import android.location.Location;
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    import android.util.Log;
    import android.widget.Toast;
    
    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.Geofence;
    import com.google.android.gms.location.GeofencingEvent;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationServices;
    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.CameraPosition;
    import com.google.android.gms.maps.model.LatLng;
    
    import java.util.ArrayList;
    
    
    public class MainActivity extends FragmentActivity
            implements
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener,
            LocationListener {
    
        private final MainActivity self = this;
        private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
        private GoogleMap mMap = null;
        private GoogleApiClient locationClient = null;
        private static final LocationRequest REQUEST = LocationRequest.create()
                .setInterval(5000)
                .setFastestInterval(16)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    
        PendingIntent pendingIntent = null;
        ArrayList<Geofence> mGeofenceList = new ArrayList<>();
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mMap = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
    
            if(mMap != null) {
                mMap.setMyLocationEnabled(true);
            }
    
            locationClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)        //利用するAPIの指定
                    .addConnectionCallbacks(this)        //接続完了リスナ
                    .addOnConnectionFailedListener(this) //接続失敗リスナ
                    .build();
            }
    
        @Override
        protected void onStart() {
            Log.d("mLocationClient", "接続");
            super.onStart();
    
            locationClient.connect();
        }
    
        @Override
        protected void onStop() {
            Log.d("mLocationClient", "接続解除");
            locationClient.disconnect();
            super.onStop();
        }
    
    
        @Override
        protected void onResume() {
            super.onResume();
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            Log.d("onNewIntent", String.valueOf(intent));
            GeofencingEvent event = GeofencingEvent.fromIntent(intent);
            int transitionType = event.getGeofenceTransition();
        }
    
        @Override
        public void onLocationChanged(Location location){
            CameraPosition cameraPos = new CameraPosition.Builder()
                    .target(new LatLng(location.getLatitude(),location.getLongitude())).zoom(17.0f)
                    .bearing(0).build();
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPos));
    
            //①ここにGeofenceの生成登録
            Geofencescheck();
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult result){
            Toast.makeText(self, "onConnectionFailed", Toast.LENGTH_LONG).show();
            addGeofence();
        }
    
        @Override
        public void onConnected(Bundle connectionHint){
            fusedLocationProviderApi.requestLocationUpdates(locationClient, REQUEST, this);
            Toast.makeText(self, "onConnected", Toast.LENGTH_LONG).show();
    
        }
    
    
        @Override
        public void onConnectionSuspended(int cause){
    
        }
    
    
        private void addGeofence() {
            // Geofence の作成 　テスト：関西国際空港
            // 緯度
            double latitude = 34.436346;
            // 経度
            double longitude = 135.244140;
            // 半径(メートル)
            float radius = 1000;
    
            //Geofenceの作成
            mGeofenceList.add(new Geofence.Builder()
                    .setRequestId("ID")
                    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
                    .setCircularRegion(latitude, longitude, radius)
                    .setExpirationDuration(Geofence.NEVER_EXPIRE)
                    .build());
    
    
            // PendingIntent の生成
            Intent intent = new Intent(self, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
    
    
        private void Geofencescheck(){
            try {
                // Geofences の登録
                LocationServices.GeofencingApi.addGeofences(locationClient, mGeofenceList, pendingIntent);
                Log.d("addGeofences", "addGeofences成功");
            } catch (Exception e) {
                e.printStackTrace();
                Log.d("addGeofences", "addGeofences失敗");
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2015-03-04T03:05:23.700
7407
2015-04-05T12:45:40.857
2015-03-06T11:59:57.330
8000
8670
question
android google-maps google-play-service
GoogleApiClientを使用したGeofenceはどのように実装するのですか？


GeofencingApiはこちら  
<https://developer.android.com/reference/com/google/android/gms/location/GeofencingApi.html>

Geofence.Builderはこちら  
<https://developer.android.com/reference/com/google/android/gms/location/Geofence.Builder.html>

wearableですがgeofenceの実装はこちら  
<https://developer.android.com/samples/Geofencing/Application/src/com.example.android.wearable.geofencing/MainActivity.html#l95>

古いですが日本語はこちら  
<http://dev.classmethod.jp/smartphone/android/android-google-play-services-
location-api-geofencing/>

* * *

# 追記：

現在地取得もそうですが、ジオフェンスにしてもGoogleApiClientをのインスタンスを作った時などにコールバックが設定され、現在地が動いた時やジオフェンスだったら領域に入ったなどのイベント発生時にonLocationChangedやインテントがでます。ゆえに提示いただいたGeofencescheck()のようなことはしなくてもイベントは出ますし、Geofencescheck()で現在地変更ごとに「領域に入った」かどうかチェックするならGeofencesは入りません。  
あと、本論とずれますがtry～catchの使い方（文法ではなくて）も違います。  
詳しく回答しようとすると、量が多いので時間がかかります。（具体例も出せてませんが・・）

他の方の回答を待つか、「インターフェース」「コールバック」「implements」について調べると解決するかもしれません。

* * *

上記を参考にしてこんなかんじはどうでしょうか。

[code]

    //GoogleApiClientの作成
    locationClient = new GoogleApiClient.Builder(getApplicationContext())
             .addApi(LocationServices.API)
             .addConnectionCallbacks(this)
             .addOnConnectionFailedListener(this)
             .build();
    
    // PendingIntent の生成
    Intent intent = new Intent(context, 伝えるactivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
    
    //Geofenceの作成
    mGeofenceList.add(new Geofence.Builder()
            .setRequestId("ID")
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
            .setCircularRegion(緯度, 経度, 半径メートル)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .build());
    
    //GeofencingApiに加える
    LocationServices.GeofencingApi.addGeofences(locationClient,mGeofenceList,
            pendingIntent);
    
[/code]


CC BY-SA 3.0
2015-03-04T05:15:41.770
7415
2015-03-06T09:31:23.303
2020-06-17T08:14:45.997
-1
7256
7407
answer