Android Geofencing API работает нормально для Wi-Fi в фоновом режиме, но не для GPS - PullRequest
0 голосов
/ 10 мая 2018

Я работаю с GeofencingClient Api. Проблема в том, что мое приложение работает нормально, когда Wi-Fi включен и запускает переход геозоны. Но в случае GPS не работает. Я хочу, чтобы служба продолжала нормально работать в фоновом режиме и продолжала запускать переходы геозоны, когда она входит и выходит из радиуса набора геозоны.

Пример кода

Код, по которому я вызываю GeofencingClient

  public static void addGeofences() {
    mGeofenceList = new ArrayList<>();
    populateGeofenceList();

    mGeofencingClient = LocationServices.getGeofencingClient(MyApplicationClass.getAppContext());


    mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    Log.d("Tag", "Test");
                }
            });
}

Код, где этот метод называется addGeofence

public class GpsLocationReceiver extends BroadcastReceiver implements LocationListener {

    LocationManager locationManager ;
    boolean GpsStatus ;
    public Context mContext;
    @Override
    public void onReceive(Context context, Intent intent) {

        MainActivity obj = new MainActivity();

        locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

        GpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        if(GpsStatus == true)
        {

            Toast.makeText(context, "GPS Enabled", Toast.LENGTH_LONG).show();
            obj. populateGeofenceList();
            obj.mGeofencingClient = LocationServices.getGeofencingClient(context);
            obj.addGeofences();


        }else {

            Toast.makeText(context, "Disabled GPS", Toast.LENGTH_LONG).show();

        }
    }

    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }
}

И код, где происходит этот переход

@Override
protected void onHandleIntent(Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);

     Context context;

    if (geofencingEvent.hasError()) {
        String errorMessage = GeofenceErrorMessages.getErrorString(this,
                geofencingEvent.getErrorCode());
        Log.e(TAG, errorMessage);
        return;
    }

    // Get the transition type.
    int geofenceTransition = geofencingEvent.getGeofenceTransition();


    //===============================

    if (geofenceTransition == 1) {
        handler.post(new Runnable() {
            @Override
            public void run() {

                attendenInRecord();

            }
        });
        Log.i(TAG, "Entered");

    }

    else {

        handler.post(new Runnable() {
            @Override
            public void run() {

                attendenOutRecord();

            }
        });
        Log.e(TAG, String.valueOf(geofenceTransition));
    }
    //===================================

    // Test that the reported transition was of interest.
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
            geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {


        // Get the geofences that were triggered. A single event can trigger multiple geofences.
        List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();

        // Get the transition details as a String.
        String geofenceTransitionDetails = getGeofenceTransitionDetails(geofenceTransition,
                triggeringGeofences);

        // Send notification and log the transition details.
        sendNotification(geofenceTransitionDetails);


        Log.i(TAG, geofenceTransitionDetails);

        if(geofenceTransition==Geofence.GEOFENCE_TRANSITION_ENTER){

            Log.i(TAG, geofenceTransitionDetails);
        }

    } else {
        // Log the error.
        Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition));

    }
}

/**
 * Gets transition details and returns them as a formatted string.
 *
 * @param geofenceTransition    The ID of the geofence transition.
 * @param triggeringGeofences   The geofence(s) triggered.
 * @return                      The transition details formatted as String.
 */
private String getGeofenceTransitionDetails(
        int geofenceTransition,
        List<Geofence> triggeringGeofences) {

    String geofenceTransitionString = getTransitionString(geofenceTransition);

    // Get the Ids of each geofence that was triggered.
    ArrayList<String> triggeringGeofencesIdsList = new ArrayList<>();
    for (Geofence geofence : triggeringGeofences) {
        triggeringGeofencesIdsList.add(geofence.getRequestId());
    }
    String triggeringGeofencesIdsString = TextUtils.join(", ",  triggeringGeofencesIdsList);

    return geofenceTransitionString + ": " + triggeringGeofencesIdsString;
}

/**
 * Posts a notification in the notification bar when a transition is detected.
 * If the user clicks the notification, control goes to the MainActivity.
 */
private void sendNotification(String notificationDetails) {
    // Get an instance of the Notification manager
    NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // Android O requires a Notification Channel.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.app_name);
        // Create the channel for the notification
        NotificationChannel mChannel =
                new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);

        // Set the Notification Channel for the Notification Manager.
        mNotificationManager.createNotificationChannel(mChannel);
    }

    // Create an explicit content Intent that starts the main Activity.
    Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);

    // Construct a task stack.
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

    // Add the main Activity to the task stack as the parent.
    stackBuilder.addParentStack(MainActivity.class);

    // Push the content Intent onto the stack.
    stackBuilder.addNextIntent(notificationIntent);

    // Get a PendingIntent containing the entire back stack.
    PendingIntent notificationPendingIntent =
            stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    // Get a notification builder that's compatible with platform versions >= 4
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

    // Define the notification settings.
    builder.setSmallIcon(R.drawable.point)
            // In a real app, you may want to use a library like Volley
            // to decode the Bitmap.
            .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                    R.drawable.point))
            .setColor(Color.RED)
            .setContentTitle(notificationDetails)
            .setContentText(getString(R.string.geofence_transition_notification_text))
            .setContentIntent(notificationPendingIntent);

    // Set the Channel ID for Android O.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        builder.setChannelId(CHANNEL_ID); // Channel ID
    }

    // Dismiss notification once the user touches it.
    builder.setAutoCancel(true);

    // Issue the notification
    mNotificationManager.notify(0, builder.build());
}

/**
 * Maps geofence transition types to their human-readable equivalents.
 *
 * @param transitionType    A transition type constant defined in Geofence
 * @return                  A String indicating the type of transition
 */
private String getTransitionString(int transitionType) {
    switch (transitionType) {

        case Geofence.GEOFENCE_TRANSITION_ENTER:


            return getString(R.string.geofence_transition_entered);

        case Geofence.GEOFENCE_TRANSITION_EXIT:

            return getString(R.string.geofence_transition_exited);
        default:
            return getString(R.string.unknown_geofence_transition);
    }
}

1 Ответ

0 голосов
/ 11 мая 2018

Попробуйте сделать это с запросом точного местоположения с помощью GPS. Я обнаружил, что при использовании грубого местоположения заборы GPS не срабатывают, но с Wi-Fi они будут знать, что вы находитесь в определенном диапазоне.

Я понимаю, что плавленое местоположение поможет этому безмерно до 1 метра в следующем году, когда Google выпустит wifiRTT. В любом случае вам нужно будет запросить точное местоположение, которое также охватывает грубое местоположение.

...