Android GeoFence не запускается
Обратите внимание, пожалуйста, прочитайте мой полный вопрос до голосования
Так что я следил за документацией, которую я нашел здесь ссылку здесь
Это мой манифест код
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-permission android:name="android.permission.INTERNET" />
Код класса обслуживания
private void startGeofence(float lat, float lon, float radius) {
Log.i("INFO", "startGeofence() in Gps Service");
System.out.println("startGeofence in GPS Service"+lat+"\t"+lon+"\t"+radius);
Geofence geofence = createGeofence( lat,lon, radius);
GeofencingRequest geofenceRequest = createGeofenceRequest( geofence );
addGeofence( geofenceRequest );
}
// Create a Geofence
private Geofence createGeofence(float lat, float lon, float radius) {
Log.d("INFO", "createGeofence");
int delay;
int time=pref.getInt("time",300000);
if (this.radius!=0){this.radius=300;}
System.out.println("Fence Service Co-ordinates in Gps Service are :::::::::::::::::::::::::::::::::::::::::::::::::: "+lat+" , "+lon+":"+ this.radius);
System.out.println("Time arrived for loitering delay in Gps Service are :::::::::::::::::::::::::::::::::::::: "+time);
if (time<=0)
delay=300000;
else
delay=time;
return new Geofence.Builder()
.setRequestId(GEOFENCE_REQ_ID)
.setCircularRegion(lat,lon,radius)
.setExpirationDuration(GEO_DURATION)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d("INFO", "createGeofenceRequest"); System.out.println(":::::::::::::::::::::::::::::::::: Request Created ::::::::::::::::::::::::::::::");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
}
@Override
public void onLowMemory() {
super.onLowMemory();
addNotification("Low memory.. removing service");
if (!googleApiClient.isConnecting() || !googleApiClient.isConnected()) {
googleApiClient.connect();
}
LocationServices.FusedLocationApi.removeLocationUpdates(this.googleApiClient, this);
LocationServices.GeofencingApi.removeGeofences(this.googleApiClient, createGeofencePendingIntent()).setResultCallback(this);
stopSelf();
}
private PendingIntent geoFencePendingIntent;
private final int GEOFENCE_REQ_CODE = 0;
private PendingIntent createGeofencePendingIntent() {
Log.d("INFO", "createGeofencePendingIntent");
System.out.println(":::::::::::::::::::::::::::::::::: createGeofencePendingIntent ::::::::::::::::::::::::::::::");
if (geoFencePendingIntent != null)
return geoFencePendingIntent;
Intent intent = new Intent(this, GeofenceTrasitionService.class);
// return PendingIntent.getService(
// this, GEOFENCE_REQ_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getService(this,GEOFENCE_REQ_CODE,intent,PendingIntent.FLAG_UPDATE_CURRENT);
if (pendingIntent == null){
System.out.println(":::::::::::::::::::::::: Service not called:::::::::::::::::::::::");
} else {
System.out.println(":::::::::::::::::::::::: Service is Alrady Called:::::::::::::::::::::::");
}
return pendingIntent;
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
Log.d("INFO", "addGeofence");
System.out.println(":::::::::::::::::::::::::::::::::: addGeofence::::::::::::::::::::::::::::::");
if (ActivityCompat.checkSelfPermission(this, android.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;
}
LocationServices.GeofencingApi.addGeofences(
googleApiClient,
request,
createGeofencePendingIntent()
).setResultCallback(this);
}
@Override
public void onResult(@NonNull Status status) {
Log.i("INFO", "onResult: " + status);
if ( status.isSuccess() ) {
System.out.println("Status Success in Fence Service");
} else {
System.out.println("Status failed in Fence Service");
}
}
private void addNotification(String message) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_action_location)
.setContentTitle("GeoFence Status")
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setContentText(message);
NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
bigText.bigText(message);
builder.setStyle(bigText);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(++notif, builder.build());
}
public void showNotification(String text, String bigText) {
// 1. Create a NotificationManager
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
// 2. Create a PendingIntent for AllGeofencesActivity
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 3. Create and send a notification
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_action_location)
.setContentTitle(text)
.setContentText(text)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setContentIntent(pendingNotificationIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
notificationManager.notify(0, notification);
}
}
GeoFenceTranstionservice.class
package com.example.vishal.geofencing;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofenceStatusCodes;
import com.google.android.gms.location.GeofencingEvent;
import java.util.ArrayList;
import java.util.List;
public class GeofenceTrasitionService extends IntentService {
private static final String TAG = GeofenceTrasitionService.class.getSimpleName();
public static final int GEOFENCE_NOTIFICATION_ID = 0;
public GeofenceTrasitionService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
// Handling errors
if ( geofencingEvent.hasError() ) {
String errorMsg = getErrorString(geofencingEvent.getErrorCode() );
System.out.println(":::::::::::::::::::::::::::::::::::::: Error in GeoFence Transition::::::::::::::::::::::::::::::"+errorMsg);
Log.e( TAG, errorMsg );
return;
}
int geoFenceTransition = geofencingEvent.getGeofenceTransition();
System.out.println("::::::::::::::::::::::::::Started Transition:::::::::::::::::::::::::::::"+geoFenceTransition);
// Check if the transition type is of interest
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT || geoFenceTransition==Geofence.GEOFENCE_TRANSITION_DWELL) {
// Get the geofence that were triggered
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences );
// Send notification details as a String
sendNotification( geofenceTransitionDetails );
}else {
System.out.println(":::::::::::::::::::::::::::::::::::::: Invalid GeoFence Transition::::::::::::::::::::::::::::::");
}
}
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
// get the ID of each geofence triggered
ArrayList<String> triggeringGeofencesList = new ArrayList<>();
for ( Geofence geofence : triggeringGeofences ) {
triggeringGeofencesList.add( geofence.getRequestId() );
}
String status = null;
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER )
status = "Entering ";
else if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT )
status = "Exiting ";
else if (geoFenceTransition==Geofence.GEOFENCE_TRANSITION_DWELL)
status="dwelling";
System.out.println("Status Of Geo Fence Transiiton is:::::::::::::::::::::::::::::::::::::::::::::::::::::::::"+status);
showNotification("GeoFence Status",status);
return status + TextUtils.join( ", ", triggeringGeofencesList);
}
private void sendNotification( String msg ) {
Log.i(TAG, "sendNotification: " + msg );
// Intent to start the main Activity
Intent notificationIntent = MainActivity.makeNotificationIntent(
getApplicationContext(), msg
);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Creating and sending Notification
NotificationManager notificatioMng =
(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
notificatioMng.notify(
GEOFENCE_NOTIFICATION_ID,
createNotification(msg, notificationPendingIntent));
}
// Create notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder
.setSmallIcon(R.drawable.ic_action_location)
.setColor(Color.RED)
.setContentTitle(msg)
.setContentText("Geofence Notification!")
.setContentIntent(notificationPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setAutoCancel(true);
return notificationBuilder.build();
}
private static String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "GeoFence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "Too many GeoFences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "Too many pending intents";
default:
return "Unknown error.";
}
}
public void showNotification(String text, String bigText) {
// 1. Create a NotificationManager
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
// 2. Create a PendingIntent for AllGeofencesActivity
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 3. Create and send a notification
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_action_location)
.setContentTitle(text)
.setContentText(text)
.setContentIntent(pendingNotificationIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
notificationManager.notify(0, notification);
}
}
После внедрения Geo Fencing в приложение также вызывается намерение Geo Fence. (радиус геозоны получается, когда пользователь добавляет 2 точки маркера, где первая говорит, что центр ограждения круга, а второй маркер определяет радиус), но служба геозоны не активируется. то есть, Geofence не вызывает PendingIntent, даже если он был успешно добавлен.
Сервис объявлен в Androidmanifest.
<service android:enabled="true" android:name=".GeofenceTrasitionService"/>