我浏览了android的地理围栏文档以及网络上的其他一些示例。它们的共同点是从活动初始化Geofencing客户端,然后添加geofence并在活动本身上分配挂起的意图。在挂起的Intent中,它们通过Intent服务类或Broadcast接收器类。我的第一个问题
如果我在活动中初始化一个类,说“ GeofenceActivity”,然后关闭该应用程序(按返回按钮,还将其从最近使用的应用程序中删除),传入的Intent服务或Broadcast接收器类是否会待定意图仍将能够获取Enter和存在的事件通知?
我可以初始化服务类中的类,并准备该类中的未决意图吗?
我需要的是,我要设置环境的方式是,即使应用程序无法运行(通过应用程序我的意思是UI,服务也将运行),我仍希望收到有关地理围栏事件的通知。
Service class:
package com.services;
import android.Manifest;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.media.MediaPlayer;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.JobIntentService;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofenceStatusCodes;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingEvent;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import receiver.GeofenceBroadcastReceiver;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class GeofenceTransitionsJobIntentService extends JobIntentService {
static MediaPlayer mp;
private static final String GEO_PENDING_KEY = "MMW-GEOFENCING-KEY";
private static PendingIntent mGeofencePendingIntent;
private static LocationRequest mLocationRequest;
public static GeofencingClient GEOFENCING_CLIENT;
private static Context geocontext;
private static CountDownTimer timer;
private static double latitude, longitude;
private static float radius;
private static ArrayList<Geofence> mGeofenceList;
private static final String IDENTIFIER = "LocationAlertIS";
int geofenceTransition;
private static final int JOB_ID = 573;
//private static final String TAG = "GeofenceTransitionsIS";
private static final String TAG = "Ganesh";
private static final String CHANNEL_ID = "channel_01";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: GEO FENCING STARTED");
SetTimerStatus(true);
PrepareGeoClient();
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy: GEO FENCING DESTROYED XXXX");
SetTimerStatus(false);
super.onDestroy();
}
public static void enqueueWork(Context context, Intent intent) {
Toast.makeText(context, "ENQUING FIRST PHASE", Toast.LENGTH_LONG).show();
enqueueWork(context, GeofenceTransitionsJobIntentService.class, JOB_ID, intent);
}
@Override
protected void onHandleWork(Intent intent) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
Toast.makeText(geocontext, "ENQUING FINAL PHASE", Toast.LENGTH_LONG).show();
}catch (Exception ex){
}
}
});
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Log.e(IDENTIFIER, "" + getErrorString(geofencingEvent.getErrorCode()));
return;
}
Log.i(IDENTIFIER, geofencingEvent.toString());
geofenceTransition = geofencingEvent.getGeofenceTransition();
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
//logic to process geofence event
}
}
private String getGeofenceTransitionInfo(List<Geofence> triggeringGeofences) {
ArrayList<String> locationNames = new ArrayList<>();
for (Geofence geofence : triggeringGeofences) {
locationNames.add(getLocationName(geofence.getRequestId()));
System.out.println("GET LOACTION NAME");
}
String triggeringLocationsString = TextUtils.join(", ", locationNames);
return triggeringLocationsString;
}
private String getLocationName(String key) {
String[] strs = key.split("-");
String locationName = null;
if (strs != null && strs.length == 2) {
double lat = Double.parseDouble(strs[0]);
double lng = Double.parseDouble(strs[1]);
locationName = getLocationNameGeocoder(lat, lng);
} else System.out.println("NULLLLLLLLLLLLLLLLL");
if (locationName != null) {
return locationName;
} else {
return key;
}
}
private String getLocationNameGeocoder(double lat, double lng) {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(lat, lng, 1);
} catch (Exception ioException) {
Log.e("", "Error in getting location name for the location");
Toast.makeText(this, "Error in getting location name for the location", Toast.LENGTH_LONG).show();
}
if (addresses == null || addresses.size() == 0) {
Log.d("", "no location name");
Toast.makeText(this, "No Location name", Toast.LENGTH_LONG).show();
return null;
} else {
Address address = addresses.get(0);
ArrayList<String> addressInfo = new ArrayList<>();
for (int i = 0; i <= address.getMaxAddressLineIndex(); i++) {
addressInfo.add(address.getAddressLine(i));
}
return TextUtils.join(System.getProperty("line.separator"), addressInfo);
}
}
private String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "Geofence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "geofence too many_geofences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "geofence too many pending_intents";
default:
return "geofence error";
}
}
private String getTransitionString(int transitionType) {
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
return "location entered";
case Geofence.GEOFENCE_TRANSITION_EXIT:
return "location exited";
case Geofence.GEOFENCE_TRANSITION_DWELL:
return "dwell at location";
default:
return "location transition";
}
}
private void notifyLocationAlert(String locTransitionType, String locationDetails) {
// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this, SettingTabMainMapActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
String CHANNEL_ID = "Zoftino";
NotificationCompat.Builder builder =
new NotificationCompat.Builder(geocontext, CHANNEL_ID)
.setSmallIcon(R.drawable.mmw_red_white_60)
.setContentTitle(locTransitionType)
.setContentText(locationDetails)
.setContentIntent(resultPendingIntent)
.setPriority(NotificationManager.IMPORTANCE_HIGH);
//Vibration
builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
//LED
builder.setLights(Color.RED, 10000, 10000);
builder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, builder.build());
}
private void triggerDetection() {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent("trigger-detection");
// You can also include some extra data.
intent.putExtra("clear", "This is my message6!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void triggerGeofence(double lat, double longs) {
Patient patient = (Patient) MedWatchApp.getCurrentUser();
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
//alert geofence exit
}
else if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER) {
//alert geofence entrance
}
static void SetTimerStatus(boolean start){
try{
if(!start) {
timer.cancel();
timer = null;
}
else{
if(timer==null){
timer = new CountDownTimer(3600000, 5000) {
@Override
public void onTick(long l) {
if(GEOFENCING_CLIENT == null){
Log.i(TAG, "onTick: GEO CLIENT NULL");
}else{
Log.i(TAG, "onTick: OK GEO CLIENT NOT NULL");
}
if(geocontext == null){
Log.i(TAG, "onTick: CONTEXT NULLLL");
}else{
Log.i(TAG, "onTick: CONTEXT FINE");
}
}
@Override
public void onFinish() {
}
};
timer.start();
}
}
}catch (Exception ex){
}
}
public static void SetGeofenceClient(GeofencingClient client){
GEOFENCING_CLIENT = client;
}
public static void ResetGeofenceClient(){
GEOFENCING_CLIENT = null;
}
public static GeofencingClient GetGeofenceingClient(){
return GEOFENCING_CLIENT;
// return null;
}
public static void SetGeoContext(Context context){
geocontext = context;
}
private static void PrepareGeoClient(){
if(GEOFENCING_CLIENT==null){
mGeofenceList = new ArrayList<>();
PrepareAllGeoCoordinate(-33.8502747,151.032907,20);
PrepareAllGeoCoordinate(-33.8502747,151.029999,20);
PrepareAllGeoCoordinate(-33.8492767,151.0328641,20);
PrepareAllGeoCoordinate(-33.8499534,151.0297315,10);
PrepareAllGeoCoordinate(-33.8500069,151.0297422,10);
PrepareAllGeoCoordinate(-33.8500247,151.0297529,10);
GEOFENCING_CLIENT = LocationServices.getGeofencingClient(geocontext);
//createLocationRequest();
RemoveGeoLocations();
}
AddGeoLocation();
}
//specifications of real location updates.
protected static void createLocationRequest() {
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(2000);
mLocationRequest.setFastestInterval(2000);
mLocationRequest.setSmallestDisplacement(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected static void RemoveGeoLocations(){
GEOFENCING_CLIENT.removeGeofences(getGeofencePendingIntent()).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(geocontext, "REMOVED>>>", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(geocontext, "FALED REMOVED>>>", Toast.LENGTH_LONG).show();
}
}
});
}
protected static void AddGeoLocation(){
if (ActivityCompat.checkSelfPermission(geocontext, Manifest.permission.ACCESS_FINE_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;
}
GEOFENCING_CLIENT.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(geocontext,
"Location alter has been added",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(geocontext,
"Geofence could not be added",
Toast.LENGTH_SHORT).show();
}
}
});
}
//geofence triggering alert process
private static PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(geocontext, GeofenceBroadcastReceiver.class);
mGeofencePendingIntent = PendingIntent.getBroadcast(geocontext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
//geofence triggering alert process
private static GeofencingRequest getGeofencingRequest(Geofence geofence) {
// The INITIAL_TRIGGER_ENTER flag indicates that geofencing service should trigger a
// GEOFENCE_TRANSITION_ENTER notification when the geofence is added and if the device
// is already inside that geofence.
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
// builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofence(geofence);
// builder.setInitialTrigger(4);
builder.addGeofences(mGeofenceList);
return builder.build();
}
//geofence triggering alert process
private static GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
// The INITIAL_TRIGGER_ENTER flag indicates that geofencing service should trigger a
// GEOFENCE_TRANSITION_ENTER notification when the geofence is added and if the device
// is already inside that geofence.
// builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER |GeofencingRequest.INITIAL_TRIGGER_DWELL);
builder.addGeofences(mGeofenceList);
return builder.build();
}
public static void SetGeoParams(double lat, double lng, float rad){
latitude = lat;
longitude = lng;
radius = rad;
}
private static void PrepareAllGeoCoordinate(double lat, double lng, int rad){
//Create dummy data for testing
mGeofenceList.add(new Geofence.Builder()
.setRequestId(String.format("%f-%f",lat,lng))
.setCircularRegion(
lat,
lng,
rad
)
.setLoiteringDelay(60000)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT | Geofence.GEOFENCE_TRANSITION_DWELL)
// Create the geofence.
.build());
//
}
}
I set the context from MainActivity calling following method in onCreate method:
void PrepareGeoFence(){
// -33.8502747,151.032907
GeofenceTransitionsJobIntentService.SetGeoContext(this);
GeofenceTransitionsJobIntentService.SetGeoParams(-33.8502747,
// 151.029999
151.032907,
10f);
this.startService(new Intent(this, GeofenceTransitionsJobIntentService.class));
}
答案 0 :(得分:1)