Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 不总是触发带有广播接收器的地理围栏_Android_Android Geofence - Fatal编程技术网

Android 不总是触发带有广播接收器的地理围栏

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

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

用于添加地理围栏的通用类:

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




}

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

我假设您已经意识到需要改进的情况 当用户禁用GPS时,您的地理围栏将被注销

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


您还可以尝试将“action\u GEOFENCE\u TRANSITION”之类的操作放在清单文件内的接收者意图过滤器中。创建挂起的意图时,将其作为操作。

检查此repo github.com/vinayakb73/geofinence-GeoFire
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);
    }
}
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);
        }
    }




}