Как заставить геозону работать на андроиде?

уже несколько дней я застрял. Я пытаюсь сделать простой тост, когда пользователь входит или выходит из геозоны, чтобы увидеть, работает ли она. И НЕТ ХОРОШЕГО пошагового руководства в Интернете, которое показывает мне, как это сделать. (Те, что от Google, не показывают мне, как тосты или вообще что-либо делать...)

Вот код моей основной деятельности.

    public class GeoFence extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {
        private static final String GEOFENCE_ID = "geoFenceID" ;
        protected GoogleApiClient mGoogleApiClient;
        private Button mAddGeofencesButton;
        private Button startLocationMonitoringButton;
        private Button startGeoFenceMonitoringButton;
        private Button stopGeoFenceMonitoringButton;


        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_geo_fence);
            mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
            startLocationMonitoringButton = (Button) findViewById(R.id.geoButton1);
            startLocationMonitoringButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startLocationMonitoring();
                }
            });
            startGeoFenceMonitoringButton = (Button) findViewById(R.id.geoButton2);
            startGeoFenceMonitoringButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startGeofenceMonitoring();
                }
            });

            stopGeoFenceMonitoringButton = (Button) findViewById(R.id.geoButton3);
            stopGeoFenceMonitoringButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stopGeoFenceMonitoring();
                }
            });
    }

    private void startLocationMonitoring() //Make a button for this
    {
        try {
            LocationRequest locationRequest = LocationRequest.create().setInterval(10000)
                    .setFastestInterval(5000)
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, new LocationListener() {
                @Override
                public void onLocationChanged(Location location)
                {

                }
            });
        }
        catch (SecurityException e)
        {

        }
    }

    private void startGeofenceMonitoring() //Make a button for this
    {
        try
        {
            Geofence geofence = new Geofence.Builder()
                    .setRequestId(GEOFENCE_ID)
                    .setCircularRegion(34.065866, -118.459572,45)
                    .setExpirationDuration(Geofence.NEVER_EXPIRE)
                    .setNotificationResponsiveness(1000)
                    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
                    .build();

            GeofencingRequest geofencingRequest = new GeofencingRequest.Builder()
                    .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
                    .addGeofence(geofence).build();

            Intent intent = new Intent(this, GeofenceService.class);
            PendingIntent pendingIntent = PendingIntent.getService(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);

            if(!mGoogleApiClient.isConnected())
            {
                //Toast not connected
            }
            else
            {
                LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, geofencingRequest,pendingIntent)
                        .setResultCallback(new ResultCallback<Status>() {
                            @Override
                            public void onResult(@NonNull Status status) {
                                if(status.isSuccess())
                                {
                                    Toast.makeText(getBaseContext(),"successful monitoring...",Toast.LENGTH_SHORT).show();
                                }
                                else
                                {
                                    //Something fucked up with our geofence bro
                                }
                            }
                        });
            }
        }
        catch (SecurityException e)
        {

        }
    }

    private void stopGeoFenceMonitoring()
    {
        ArrayList<String> geofenceIds = new ArrayList<>();
        geofenceIds.add(GEOFENCE_ID);
        LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,geofenceIds);
    }
}

Вот мой класс GeofenceService, где, я думаю, я должен произнести тост?

public class GeofenceService extends IntentService
{

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public static final String TAG = "GeofenceService";
    public GeofenceService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {
        GeofencingEvent event = GeofencingEvent.fromIntent(intent);
        if(event.hasError())
        {

        }
        else
        {
            int transition = event.getGeofenceTransition();
            List<Geofence> geofences = event.getTriggeringGeofences();
            Geofence geofence = geofences.get(0);
            String requestId = geofence.getRequestId();
            if(transition == Geofence.GEOFENCE_TRANSITION_ENTER)
            {
                Toast.makeText(getBaseContext(),"Entering GeoFence",Toast.LENGTH_SHORT).show();
            }
            else if(transition == Geofence.GEOFENCE_TRANSITION_EXIT)
            {
                Toast.makeText(getBaseContext(),"Leaving GeoFence",Toast.LENGTH_SHORT).show();
            }
        }
    }
}

Наконец вот мой xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/add_geofences_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:onClick="addGeofencesButtonHandler"
        android:text="Add GeoFences" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Location Monitoring"
        android:id="@+id/geoButton1"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start GeoFence Monitoring"
        android:id="@+id/geoButton2"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop GeoFence Monitoring"
        android:id="@+id/geoButton3"/>
</LinearLayout>

Если у кого-то из вас, ребята, есть ПРОСТЫЕ пошаговые руководства или код о том, как сделать простую геозону с отображением всплывающего уведомления о входе или выходе из геозоны, это было бы здорово! И/или вы также можете проверить мой существующий код, чтобы увидеть, не пропустил ли я что-то. КОД ЗАПУСКАЕТСЯ, но ничего не происходит...


person Dr.Android    schedule 25.09.2016    source источник
comment
1. В своем onHandleIntent вы смотрите только на свою первую геозону. 2. В учебнике есть раздел 5 с кодом. 3. Как вы тестируете свою геозону (устройство/эмулятор/имитатор геозоны)? 4.4. Чуть другой пример Google для геозоны находится здесь: github.com/googlesamples/android-Geofencing.   -  person Morrison Chang    schedule 25.09.2016
comment
@MorrisonChang 1. Итак, я специально установил только одну геозону, просто чтобы посмотреть, смогу ли я заставить ее работать с одной геозоной. Я полагаю, что у меня более 1 геозоны, и что вы подразумеваете под поиском? 2. Вы имеете в виду учебник, который вы разместили, какой учебник вы имеете в виду? 3. Я тестирую на устройстве, поэтому я физически вхожу в геозону, чтобы посмотреть, будет ли это тост. Спасибо за первый ответ, надеюсь, вы сможете ответить на мои следующие вопросы.   -  person Dr.Android    schedule 25.09.2016
comment
1. взгляд = ссылка — поскольку вы используете только первую запись близости — все должно быть в порядке 2. Учебное пособие, на которое вы ссылались в своем предыдущем вопросе: io2015codelabs.appspot.com/codelabs/geofences#5 3. Я бы удлинил ваш ответ на уведомление более чем на 1 секунду. Особенно при использовании устройства для управления питанием. перемещая устройство, вы можете попробовать Mock Geo Provider.   -  person Morrison Chang    schedule 25.09.2016
comment
@MorrisonChang У вас есть ссылка на фиктивный гео-провайдер?   -  person Dr.Android    schedule 25.09.2016
comment
@MorrisonChang, так что вы не видите ничего плохого в коде? Я постараюсь увеличить время ответа на уведомление.   -  person Dr.Android    schedule 25.09.2016


Ответы (1)


Была такая же проблема. GoogleApiClient больше не используется. Этот класс разделен на несколько других: https://developers.google.com/android/guides/google-api-client . Теперь вам нужно использовать GeofenceClient, у которого очень похожий подход.

https://developer.android.com/training/location/geofencing

Короче говоря, вам просто нужно использовать GeofencingClient вместо GoogleApiClient.

private PendingIntent getGeofencePendingIntent() {
    // Reuse the PendingIntent if we already have it.
    if (mGeofencePendingIntent != null) {
        return mGeofencePendingIntent;
    }
    Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
    // calling addGeofences() and removeGeofences().
    mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.
            FLAG_UPDATE_CURRENT);
    return mGeofencePendingIntent;
}

Используйте ссылку, указанную выше, для полного примера.

person Artūras Stifanovičius    schedule 31.07.2018