簡體   English   中英

我想在Android Studio中退出Geofence時推送通知

[英]I want to push a notification when exiting a Geofence in android studio

我正在為我的大學創建一個應在Android Studio中進入或退出地理圍欄時推送通知的應用程序。 問題是我無法想出任何方法來編碼在退出地理圍欄時發送通知,但進入地理圍欄時則可以正常工作。 這是我的代碼,謝謝

主要活動

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);
    }

命名Geofence類

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  
}

恆定班

public class Constants {
    public static class SharedPrefs {
        public static String Geofences = "SHARED_PREFS_GEOFENCES";
    }
}

我們是否在為您服務(應在何處放置通知)

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
}

在您的NamedGeofence類中,將.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)更改為.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) 否則,您將僅監視enter事件。

過渡類型應設置為逐位OR ,如前所述這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM