代码之家  ›  专栏  ›  技术社区  ›  matip

带BroadcastReceiver的地理围栏并不总是被触发

  •  9
  • matip  · 技术社区  · 7 年前

    在我在应用程序中使用geofreence之前,我使用intentservice作为回调,一切都正常。但现在,由于Android8的变化,我无法再启动这样的服务了。所以现在我用BroadcastReceiver作为地理围栏回调,那个接收器正在启动服务(Android8的前台)。但随着这一变化,我注意到地理围栏不再有效。它通常根本不被触发,我认为更糟糕的情况是应用程序在前台。最好的情况是,当应用程序被杀时,地理围栏就会被触发。广播接收器和地理围栏有问题吗?还是我做错了什么?我提供我的代码:

    添加地理围栏的通用类:

    public abstract class BaseGeofence<T extends BaseGeofenceObject> implements OnSuccessListener<Void>, OnFailureListener {
        protected int RADIUS_IN_METERS = 300;
        protected GeofencingClient client;
        protected Context context;
    
        public BaseGeofence(Context context) {
            this.client = LocationServices.getGeofencingClient(context);
            this.context = context;
        }
    
        @SuppressLint("MissingPermission")
        public void addGeofencing(final T object) {
            if (GPSUtils.wasLocationChecked()) {
                Geofence geofence = (new Geofence.Builder()
                        .setRequestId(Integer.toString(getId(object)))
    
                        .setCircularRegion(
                                object.getLat(),
                                object.getLon(),
                                RADIUS_IN_METERS
                        )
                        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                                Geofence.GEOFENCE_TRANSITION_EXIT)
                        .setExpirationDuration(Geofence.NEVER_EXPIRE)
                        .build());
                client.addGeofences(getGeofencingRequest(geofence), getGeofencePendingIntent(object))
                        .addOnSuccessListener(this).addOnFailureListener(this);
            }
    
    
        }
    
        private GeofencingRequest getGeofencingRequest(Geofence geofence) {
            GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
            builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
            builder.addGeofence(geofence);
            return builder.build();
        }
    
        private PendingIntent getGeofencePendingIntent(T object) {
            return PendingIntent.getBroadcast(context, getId(object), createIntent(object), PendingIntent.FLAG_UPDATE_CURRENT);
        }
    
        protected abstract Intent createIntent(T object);
    
        protected abstract int getId(T object);
    
        @Override
        public abstract void onSuccess(Void aVoid);
    
        @Override
        public abstract void onFailure(@NonNull Exception e);
    }
    

    我的地理围栏等级:

    public class MyGeofencing extends BaseGeofence<MyObject> {
    
            private MyObject myObject;
    
            public MyGeofencing(Context context) {
                super(context);
            }
    
            @Override
            protected Intent createIntent(MyObject object) {
                this.myObject = object;
                Intent intent = new Intent(context, GeofenceTransitionsReceiver.class);
    
                //put extras to intent 
    
                return intent;
            }
    
            @Override
            public void addGeofencing(MyObject object) {
                if (object.getGeofencingRadius() == 0) RADIUS_IN_METERS = 300;
                else RADIUS_IN_METERS = object.getGeofencingRadius();
                super.addGeofencing(object);
            }
    
            @Override
            protected int getId(MyObject object) {
                return object.getId();
            }
    
    
    
        }
    

    我的接收器:

    public class GeofenceTransitionsReceiver extends StartingServiceBroadcastReceiver {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (GeofencingEvent.fromIntent(intent) != null && GeofencingEvent.fromIntent(intent).getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_ENTER) {
    
                startConnectionService(context, "extra");
    
    
            } else if (GeofencingEvent.fromIntent(intent) != null && GeofencingEvent.fromIntent(intent).getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_EXIT) {
                // do something
            }
        }
    
    protected void startConnectionService(Context context, String extra) {
            Intent beaconIntent = new Intent(context, BeaconConnectionService.class);
            beaconIntent.putExtra("extra", extra);        
            startService(context, beaconIntent);
        }
    }
    

    StartingServiceBroadcastReceiver如果是Android 8或其他普通服务,则启动前台服务

    public abstract class StartingServiceBroadcastReceiver extends BroadcastReceiver {
        @Override
        public abstract void onReceive(Context context, Intent intent);
    
        protected void startService(Context context, Intent intent) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent);
            } else context.startService(intent);
        }
    }
    

    我的服务扩展了flexibleforegroundservice,如果需要,它将启动前台通知:

    public class FlexibleForegroundService extends Service {
    
        private static final String CHANNEL_ID = "test";
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            makeServiceForegroundIfNeeded();
        }
    
        public void stopService(){
            stopSelf();
        }
    
        private void makeServiceForegroundIfNeeded() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                createNotificationChannel();
    
                String message = "test";
    
                Notification notification =
                        new Notification.Builder(this, CHANNEL_ID)
                                .setContentTitle("test")
                                .setStyle(new Notification.BigTextStyle()
                                        .bigText(message))
                                .setContentText(message)
                                .setSmallIcon(R.mipmap.ic_launcher)
                                .build();
    
                startForeground(1, notification);
            }
        }
    
    
        private void createNotificationChannel() {
            // Create the NotificationChannel, but only on API 26+ because
            // the NotificationChannel class is new and not in the support library
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                int importance = NotificationManager.IMPORTANCE_DEFAULT;
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Information", importance);
                channel.setDescription("test");
                // Register the channel with the system; you can't change the importance
                // or other notification behaviors after this
                NotificationManager notificationManager = getSystemService(NotificationManager.class);
                notificationManager.createNotificationChannel(channel);
            }
        }
    
    
    
    
    }
    

    有什么方法可以改进所有安卓设备上地理围栏的工作吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Vicky    7 年前

    我假设你已经知道你必须知道的情况 Reregister geofences 当用户禁用GPS时,您的地理围栏将被注销。

    我所观察到的是,当您使用位置服务(如地图打开时)时,您会更频繁地获得地理围栏事件。

    您还可以尝试在清单文件的接收者意图过滤器中放入“action_geofience_transition”之类的操作吗?创建待定意图时将其与操作放在一起。

    推荐文章