Я создаю приложение для своего университета, которое должно вызывать уведомление при входе или выходе из геосферы в андроид-студии. Проблема в том, что я не могу думать о том, как код для отправки уведомления при выходе из геолокации, но уведомление при вводе геозонности отлично работает. вот мой код заранее спасибоЯ хочу нажать уведомление при выходе из Geofence в студии android
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GeofenceController.getInstance().init(this);
NamedGeofense geofence = new NamedGeofense();
geofence.name ="abbott";
geofence.latitude =38.037847; //your lati and longii :)
geofence.longitude =23.70083;
geofence.radius =100;
GeofenceController.getInstance().addGeofence(geofence);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
класс NamedGeofence класс
package com.example.adeeb.webviewfordigitalwaiter;
import com.google.android.gms.location.Geofence;
import java.util.UUID;
public class NamedGeofense {
public String id;
public String name;
public double latitude;
public double longitude;
public float radius;
// end region
// region Public
public Geofence geofence() {
id = UUID.randomUUID().toString();
// UUID is universal unique identifer. ref for you
// : https://docs.oracle.com/javase/7/docs/api/java/util/UUID.html
return new Geofence.Builder()
.setRequestId(id)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
}
}
Геозоны Контроллер
package com.example.adeeb.webviewfordigitalwaiter;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GeofenceController {
// region Properties
private final String TAG = GeofenceController.class.getName();
private Context context;
private GoogleApiClient googleApiClient;
private Gson gson;
private SharedPreferences prefs;
private GeofenceControllerListener listener;
private List<NamedGeofense> namedGeofences;
private Geofence geofenceToAdd;
private NamedGeofense namedGeofenceToAdd;
// endregion
// region Shared Instance
private static GeofenceController INSTANCE;
public static GeofenceController getInstance() {
if (INSTANCE == null) {
INSTANCE = new GeofenceController();
}
return INSTANCE;
}
// endregion
// region Public
//we call this from main activity (in main activity we mde an instance of geofence controller
// using static method getInstance() (like this GeofenceController.getInstance().init(this);)
public void init(Context context) {
this.context = context.getApplicationContext();
gson = new Gson();
// namedGeofences is arraylist of my defined class name (namedGeofences)
// i will discuss namedGeofences class .. wait a moment.. :P
namedGeofences = new ArrayList<>();
prefs = this.context.getSharedPreferences(Constants.SharedPrefs.Geofences, Context.MODE_PRIVATE);
// prefs is shared prefrence (shared is a class or local storage where we store data so that
// our data might not lost when we move to other class or activity)
// variable.we assign our shared prefrence name which is define in Constants class
//public static String Geofences = "SHARED_PREFS_GEOFENCES";
loadGeofences();
// loadGeofences(); is my define method where we load geofences data if they are store
// in our sharedprefrences
}
// region ConnectionCallbacks
private GoogleApiClient.ConnectionCallbacks connectionAddListener = new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Intent intent = new Intent(context, AreWeThereIntentService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingResult<Status> result = LocationServices.GeofencingApi.
addGeofences(googleApiClient, getAddGeofencingRequest(), pendingIntent);
result.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
saveGeofence();
} else {
Log.e(TAG, "Registering geofence failed: " + status.getStatusMessage() + " : " + status.getStatusCode());
sendError();
}
}
});
}
@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "Connecting to GoogleApiClient suspended.");
sendError();
}
};
public void addGeofence(NamedGeofense namedGeofence) {
this.namedGeofenceToAdd = namedGeofence;
this.geofenceToAdd = namedGeofence.geofence();
connectWithCallbacks(connectionAddListener);
}
// endregion
private GeofencingRequest getAddGeofencingRequest() {
List<Geofence> geofencesToAdd = new ArrayList<>();
geofencesToAdd.add(geofenceToAdd);
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(geofencesToAdd);
return builder.build();
}
private void saveGeofence() {
namedGeofences.add(namedGeofenceToAdd);
String json = gson.toJson(namedGeofenceToAdd);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(namedGeofenceToAdd.id, json);
editor.apply();
}
public interface GeofenceControllerListener {
void onGeofencesUpdated();
void onError();
}
public List<NamedGeofense> getNamedGeofences() {
return namedGeofences;
}
// endregion
// region Private
private void loadGeofences() {
// Map<String, ?> is A Map is a data structure consisting of a set of keys and values
// in which each key is mapped to a single value.
// we load geofences data if they are store
// in our sharedprefrences
Map<String, ?> keys = prefs.getAll();
// Loop over all geofence keys in prefs and add to namedGeofences
for (Map.Entry<String, ?> entry : keys.entrySet()) {
String jsonString = prefs.getString(entry.getKey(), null);
// gson is a library where we can store our whole class instance,
// below we assign previously store NamedGeofence class , and jsonString is key of that
// class
NamedGeofense namedGeofence = gson.fromJson(jsonString, NamedGeofense.class);
// than here we just add namedGeofence instance to our array list
namedGeofences.add(namedGeofence);
}
// Sort namedGeofences by name
}
private void connectWithCallbacks(GoogleApiClient.ConnectionCallbacks callbacks) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(connectionFailedListener)
.build();
googleApiClient.connect();
}
private void sendError() {
if (listener != null) {
listener.onError();
}
}
// endregion
// region OnConnectionFailedListener
private GoogleApiClient.OnConnectionFailedListener connectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "Connecting to GoogleApiClient failed.");
sendError();
}
};
// endregion
// region Interfaces
// end region
}
Constant класс
public class Constants {
public static class SharedPrefs {
public static String Geofences = "SHARED_PREFS_GEOFENCES";
}
}
МЫ ТАМ ДА СЕРВИС (HERES ЭТО ГДЕ УВЕДОМЛЕНИЯ ДОЛЖНО PUT)
package com.example.adeeb.webviewfordigitalwaiter;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class AreWeThereIntentService extends IntentService {
// region Properties
private final String TAG = AreWeThereIntentService.class.getName();
private SharedPreferences prefs;
private Gson gson;
// endregion
// region Constructors
public AreWeThereIntentService() {
super("AreWeThereIntentService");
}
// endregion
// region Overrides
@Override
protected void onHandleIntent(Intent intent) {
prefs = getApplicationContext().getSharedPreferences(Constants.SharedPrefs.Geofences, Context.MODE_PRIVATE);
gson = new Gson();
Log.e(TAG, "on handle :)");
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event != null) {
Log.e(TAG, "event not null :) ");
if (event.hasError()) {
onError(event.getErrorCode());
} else {
int transition = event.getGeofenceTransition();
if (transition == Geofence.GEOFENCE_TRANSITION_ENTER || transition == Geofence.GEOFENCE_TRANSITION_EXIT) {
List<String> geofenceIds = new ArrayList<>();
for (Geofence geofence : event.getTriggeringGeofences()) {
geofenceIds.add(geofence.getRequestId());
}
if (transition == Geofence.GEOFENCE_TRANSITION_ENTER || transition == Geofence.GEOFENCE_TRANSITION_EXIT) {
onEnteredGeofences(geofenceIds);
Log.e(TAG, "transition enter :) ");
}
}
}
}
}
// endregion
// region Private
private void onEnteredGeofences(List<String> geofenceIds) {
Log.e(TAG, "on entergeofense: ");
for (String geofenceId : geofenceIds) {
String geofenceName = "";
// Loop over all geofence keys in prefs and retrieve NamedGeofence from SharedPreference
Map<String, ?> keys = prefs.getAll();
for (Map.Entry<String, ?> entry : keys.entrySet()) {
String jsonString = prefs.getString(entry.getKey(), null);
NamedGeofense namedGeofence = gson.fromJson(jsonString, NamedGeofense.class);
if (namedGeofence.id.equals(geofenceId)) {
geofenceName = namedGeofence.name;
break;
}
}
// Set the notification text and send the notification
//String contextText = String.format("you entered in meeting room", geofenceName);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, GeofenceMain.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.pizaper2)
.setContentTitle("Welcome to geofense")
.setContentText("hello KOKALIS")
.setContentIntent(pendingNotificationIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText("hello KOKALIS"))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build(); // id
notificationManager.notify(0, notification);
Log.e(TAG, "notifications: ");
}
}
private void onError(int i) {
Log.e(TAG, "Geofencing Error: " + i);
}
// endregion
}