越过地理围栏时执行哪个方法?
Which method gets executed when the geofence is crossed?
我正在尝试构建一个应用程序,在越过地理围栏时向另一个 phone 发送短信。我从 google 示例地理围栏中借用了代码。我想知道调用地理围栏时执行了什么方法。我尝试将我的代码放入 getGeofencePendingIntent 方法中(如评论所示)。但是,这会导致每当单击“添加地理围栏”或“删除地理围栏”按钮时都会发送一条 SMS。通知(来自 GeofenceTransitionsIntentService class)也没有被执行。
我试图将我的代码放入 GeofenceTransitionsIntentService class 本身,因为我认为当越过地理围栏时,存在的任何代码都会被执行。但是,这导致通知和短信无法执行。
发送短信的代码如下:
String phoneNum = editText2.getText().toString();
if (phoneNum.length()>9 && phoneNum.length()<11) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNum, null, "This is part of an SMS text message!", null, null);
}
else
{
// display message if text fields are empty
Toast.makeText(getBaseContext(),"Please add a correct phone number.",Toast.LENGTH_SHORT).show();
}
这是我在 SetGeofence (Main Activity) 中的代码 class:
package com.indianstudentroom.senioralert;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import java.util.ArrayList;
import java.util.Map;
public class SetGeofence extends AppCompatActivity implements OnCompleteListener<Void> {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_geofence);
// Get the UI widgets.
mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
mRemoveGeofencesButton = (Button) findViewById(R.id.remove_geofences_button);
openMonitoringButton = (Button) findViewById(R.id.button);
editText2 = (EditText) findViewById(R.id.edit_text);
// Empty list for storing geofences.
mGeofenceList = new ArrayList<>();
// Initially set the PendingIntent used in addGeofences() and removeGeofences() to null.
mGeofencePendingIntent = null;
setButtonsEnabledState();
// Get the geofences used. Geofence data is hard coded in this sample.
populateGeofenceList();
mGeofencingClient = LocationServices.getGeofencingClient(this);
}
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
/**
* Tracks whether the user requested to add or remove geofences, or to do neither.
*/
private enum PendingGeofenceTask {
ADD, REMOVE, NONE
}
/**
* Provides access to the Geofencing API.
*/
private GeofencingClient mGeofencingClient;
/**
* The list of geofences used in this sample.
*/
private ArrayList<Geofence> mGeofenceList;
/**
* Used when requesting to add or remove geofences.
*/
private PendingIntent mGeofencePendingIntent;
// Buttons for kicking off the process of adding or removing geofences.
private Button mAddGeofencesButton;
private Button mRemoveGeofencesButton;
public EditText editText2;
private Button openMonitoringButton;
private PendingGeofenceTask mPendingGeofenceTask = PendingGeofenceTask.NONE;
@Override
public void onStart() {
super.onStart();
if (!checkPermissions()) {
requestPermissions();
} else {
performPendingGeofenceTask();
}
}
/**
* Builds and returns a GeofencingRequest. Specifies the list of geofences to be monitored.
* Also specifies how the geofence notifications are initially triggered.
*/
private 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);
// Add the geofences to be monitored by geofencing service.
builder.addGeofences(mGeofenceList);
// Return a GeofencingRequest.
return builder.build();
}
/**
* Adds geofences, which sets alerts to be notified when the device enters or exits one of the
* specified geofences. Handles the success or failure results returned by addGeofences().
*/
public void addGeofencesButtonHandler(View view) {
if (!checkPermissions()) {
mPendingGeofenceTask = PendingGeofenceTask.ADD;
requestPermissions();
return;
}
addGeofences();
}
/**
* Adds geofences. This method should be called after the user has granted the location
* permission.
*/
@SuppressWarnings("MissingPermission")
private void addGeofences() {
if (!checkPermissions()) {
showSnackbar(getString(R.string.insufficient_permissions));
return;
}
mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnCompleteListener(this);
}
/**
* Removes geofences, which stops further notifications when the device enters or exits
* previously registered geofences.
*/
public void removeGeofencesButtonHandler(View view) {
if (!checkPermissions()) {
mPendingGeofenceTask = PendingGeofenceTask.REMOVE;
requestPermissions();
return;
}
removeGeofences();
}
/**
* Removes geofences. This method should be called after the user has granted the location
* permission.
*/
@SuppressWarnings("MissingPermission")
private void removeGeofences() {
if (!checkPermissions()) {
showSnackbar(getString(R.string.insufficient_permissions));
return;
}
mGeofencingClient.removeGeofences(getGeofencePendingIntent()).addOnCompleteListener(this);
}
public void openMonitoring() {
Intent intent = new Intent(SetGeofence.this, Monitoring.class);
startActivity(intent);
}
/**
* Runs when the result of calling {@link #addGeofences()} and/or {@link #removeGeofences()}
* is available.
*
* @param task the resulting Task, containing either a result or error.
*/
@Override
public void onComplete(@NonNull Task<Void> task) {
mPendingGeofenceTask = PendingGeofenceTask.NONE;
if (task.isSuccessful()) {
updateGeofencesAdded(!getGeofencesAdded());
setButtonsEnabledState();
int messageId = getGeofencesAdded() ? R.string.geofences_added :
R.string.geofences_removed;
Toast.makeText(this, getString(messageId), Toast.LENGTH_SHORT).show();
if (getString(messageId).equals(R.string.geofences_added)) {
openMonitoring();
}
} else {
// Get the status code for the error and log it using a user-friendly message.
String errorMessage = GeofenceErrorMessages.getErrorString(this, task.getException());
Log.w(TAG, errorMessage);
}
}
/**
* Gets a PendingIntent to send with the request to add or remove Geofences. Location Services
* issues the Intent inside this PendingIntent whenever a geofence transition occurs for the
* current list of geofences.
*
* @return A PendingIntent for the IntentService that handles geofence transitions.
*/
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
/* String phoneNum = editText2.getText().toString();
if (phoneNum.length()>9 && phoneNum.length()<11) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNum, null, "The person under your care has left the geofence! Please take the appropriate action and save them!", null, null);
}
else
{
// display message if text fields are empty
Toast.makeText(getBaseContext(),"Please add a correct phone number.",Toast.LENGTH_SHORT).show();
}
*/
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
// addGeofences() and removeGeofences().
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
* This sample hard codes geofence data. A real app might dynamically create geofences based on
* the user's location.
*/
private void populateGeofenceList() {
for (Map.Entry<String, LatLng> entry : Constants.BAY_AREA_LANDMARKS.entrySet()) {
mGeofenceList.add(new Geofence.Builder()
// Set the request ID of the geofence. This is a string to identify this
// geofence.
.setRequestId(entry.getKey())
// Set the circular region of this geofence.
.setCircularRegion(
entry.getValue().latitude,
entry.getValue().longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
// Set the expiration duration of the geofence. This geofence gets automatically
// removed after this period of time.
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
// Set the transition types of interest. Alerts are only generated for these
// transition. We track entry and exit transitions in this sample.
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
// Create the geofence.
.build());
}
}
/**
* Ensures that only one button is enabled at any time. The Add Geofences button is enabled
* if the user hasn't yet added geofences. The Remove Geofences button is enabled if the
* user has added geofences.
*/
private void setButtonsEnabledState() {
if (getGeofencesAdded()) {
mAddGeofencesButton.setEnabled(false);
mRemoveGeofencesButton.setEnabled(true);
openMonitoringButton.setEnabled(true);
} else {
mAddGeofencesButton.setEnabled(true);
mRemoveGeofencesButton.setEnabled(false);
openMonitoringButton.setEnabled(false);
}
}
public void openMonitoring(View view) {
Intent i = new Intent(SetGeofence.this, Monitoring.class);
startActivity(i);
}
/**
* Shows a {@link Snackbar} using {@code text}.
*
* @param text The Snackbar text.
*/
private void showSnackbar(final String text) {
View container = findViewById(android.R.id.content);
if (container != null) {
Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
}
}
/**
* Shows a {@link Snackbar}.
*
* @param mainTextStringId The id for the string resource for the Snackbar text.
* @param actionStringId The text of the action item.
* @param listener The listener associated with the Snackbar action.
*/
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(
findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
/**
* Returns true if geofences were added, otherwise false.
*/
private boolean getGeofencesAdded() {
return PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
Constants.GEOFENCES_ADDED_KEY, false);
}
/**
* Stores whether geofences were added ore removed in {SharedPreferences };
*
* @param added Whether geofences were added or removed.
*/
private void updateGeofencesAdded(boolean added) {
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putBoolean(Constants.GEOFENCES_ADDED_KEY, added)
.apply();
}
/**
* Performs the geofencing task that was pending until location permission was granted.
*/
private void performPendingGeofenceTask() {
if (mPendingGeofenceTask == PendingGeofenceTask.ADD) {
addGeofences();
} else if (mPendingGeofenceTask == PendingGeofenceTask.REMOVE) {
removeGeofences();
}
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
// Provide an additional rationale to the user. This would happen if the user denied the
// request previously, but didn't check the "Don't ask again" checkbox.
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
showSnackbar(R.string.permission_rationale, android.R.string.ok,
new View.OnClickListener() {
@Override
public void onClick(View view) {
// Request permission
ActivityCompat.requestPermissions(SetGeofence.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
});
} else {
Log.i(TAG, "Requesting permission");
// Request permission. It's possible this can be auto answered if device policy
// sets the permission in a given state or the user denied the permission
// previously and checked "Never ask again".
ActivityCompat.requestPermissions(SetGeofence.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted.");
performPendingGeofenceTask();
} else {
// Permission denied.
// Notify the user via a SnackBar that they have rejected a core permission for the
// app, which makes the Activity useless. In a real app, core permissions would
// typically be best requested during a welcome-screen flow.
// Additionally, it is important to remember that a permission might have been
// rejected without asking the user for permission (device policy or "Never ask
// again" prompts). Therefore, a user interface affordance is typically implemented
// when permissions are denied. Otherwise, your app could appear unresponsive to
// touches or interactions which have required permissions.
showSnackbar(R.string.permission_denied_explanation, R.string.settings,
new View.OnClickListener() {
@Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
mPendingGeofenceTask = PendingGeofenceTask.NONE;
}
}
}
}
非常感谢!
onHandleIntent
on GeofenceTransitionsIntentService
应在您的地理围栏为 entered/exited 时执行。 Post 你在该方法中的代码
我正在尝试构建一个应用程序,在越过地理围栏时向另一个 phone 发送短信。我从 google 示例地理围栏中借用了代码。我想知道调用地理围栏时执行了什么方法。我尝试将我的代码放入 getGeofencePendingIntent 方法中(如评论所示)。但是,这会导致每当单击“添加地理围栏”或“删除地理围栏”按钮时都会发送一条 SMS。通知(来自 GeofenceTransitionsIntentService class)也没有被执行。
我试图将我的代码放入 GeofenceTransitionsIntentService class 本身,因为我认为当越过地理围栏时,存在的任何代码都会被执行。但是,这导致通知和短信无法执行。
发送短信的代码如下:
String phoneNum = editText2.getText().toString();
if (phoneNum.length()>9 && phoneNum.length()<11) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNum, null, "This is part of an SMS text message!", null, null);
}
else
{
// display message if text fields are empty
Toast.makeText(getBaseContext(),"Please add a correct phone number.",Toast.LENGTH_SHORT).show();
}
这是我在 SetGeofence (Main Activity) 中的代码 class:
package com.indianstudentroom.senioralert;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import java.util.ArrayList;
import java.util.Map;
public class SetGeofence extends AppCompatActivity implements OnCompleteListener<Void> {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_geofence);
// Get the UI widgets.
mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
mRemoveGeofencesButton = (Button) findViewById(R.id.remove_geofences_button);
openMonitoringButton = (Button) findViewById(R.id.button);
editText2 = (EditText) findViewById(R.id.edit_text);
// Empty list for storing geofences.
mGeofenceList = new ArrayList<>();
// Initially set the PendingIntent used in addGeofences() and removeGeofences() to null.
mGeofencePendingIntent = null;
setButtonsEnabledState();
// Get the geofences used. Geofence data is hard coded in this sample.
populateGeofenceList();
mGeofencingClient = LocationServices.getGeofencingClient(this);
}
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
/**
* Tracks whether the user requested to add or remove geofences, or to do neither.
*/
private enum PendingGeofenceTask {
ADD, REMOVE, NONE
}
/**
* Provides access to the Geofencing API.
*/
private GeofencingClient mGeofencingClient;
/**
* The list of geofences used in this sample.
*/
private ArrayList<Geofence> mGeofenceList;
/**
* Used when requesting to add or remove geofences.
*/
private PendingIntent mGeofencePendingIntent;
// Buttons for kicking off the process of adding or removing geofences.
private Button mAddGeofencesButton;
private Button mRemoveGeofencesButton;
public EditText editText2;
private Button openMonitoringButton;
private PendingGeofenceTask mPendingGeofenceTask = PendingGeofenceTask.NONE;
@Override
public void onStart() {
super.onStart();
if (!checkPermissions()) {
requestPermissions();
} else {
performPendingGeofenceTask();
}
}
/**
* Builds and returns a GeofencingRequest. Specifies the list of geofences to be monitored.
* Also specifies how the geofence notifications are initially triggered.
*/
private 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);
// Add the geofences to be monitored by geofencing service.
builder.addGeofences(mGeofenceList);
// Return a GeofencingRequest.
return builder.build();
}
/**
* Adds geofences, which sets alerts to be notified when the device enters or exits one of the
* specified geofences. Handles the success or failure results returned by addGeofences().
*/
public void addGeofencesButtonHandler(View view) {
if (!checkPermissions()) {
mPendingGeofenceTask = PendingGeofenceTask.ADD;
requestPermissions();
return;
}
addGeofences();
}
/**
* Adds geofences. This method should be called after the user has granted the location
* permission.
*/
@SuppressWarnings("MissingPermission")
private void addGeofences() {
if (!checkPermissions()) {
showSnackbar(getString(R.string.insufficient_permissions));
return;
}
mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnCompleteListener(this);
}
/**
* Removes geofences, which stops further notifications when the device enters or exits
* previously registered geofences.
*/
public void removeGeofencesButtonHandler(View view) {
if (!checkPermissions()) {
mPendingGeofenceTask = PendingGeofenceTask.REMOVE;
requestPermissions();
return;
}
removeGeofences();
}
/**
* Removes geofences. This method should be called after the user has granted the location
* permission.
*/
@SuppressWarnings("MissingPermission")
private void removeGeofences() {
if (!checkPermissions()) {
showSnackbar(getString(R.string.insufficient_permissions));
return;
}
mGeofencingClient.removeGeofences(getGeofencePendingIntent()).addOnCompleteListener(this);
}
public void openMonitoring() {
Intent intent = new Intent(SetGeofence.this, Monitoring.class);
startActivity(intent);
}
/**
* Runs when the result of calling {@link #addGeofences()} and/or {@link #removeGeofences()}
* is available.
*
* @param task the resulting Task, containing either a result or error.
*/
@Override
public void onComplete(@NonNull Task<Void> task) {
mPendingGeofenceTask = PendingGeofenceTask.NONE;
if (task.isSuccessful()) {
updateGeofencesAdded(!getGeofencesAdded());
setButtonsEnabledState();
int messageId = getGeofencesAdded() ? R.string.geofences_added :
R.string.geofences_removed;
Toast.makeText(this, getString(messageId), Toast.LENGTH_SHORT).show();
if (getString(messageId).equals(R.string.geofences_added)) {
openMonitoring();
}
} else {
// Get the status code for the error and log it using a user-friendly message.
String errorMessage = GeofenceErrorMessages.getErrorString(this, task.getException());
Log.w(TAG, errorMessage);
}
}
/**
* Gets a PendingIntent to send with the request to add or remove Geofences. Location Services
* issues the Intent inside this PendingIntent whenever a geofence transition occurs for the
* current list of geofences.
*
* @return A PendingIntent for the IntentService that handles geofence transitions.
*/
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
/* String phoneNum = editText2.getText().toString();
if (phoneNum.length()>9 && phoneNum.length()<11) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNum, null, "The person under your care has left the geofence! Please take the appropriate action and save them!", null, null);
}
else
{
// display message if text fields are empty
Toast.makeText(getBaseContext(),"Please add a correct phone number.",Toast.LENGTH_SHORT).show();
}
*/
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
// addGeofences() and removeGeofences().
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
* This sample hard codes geofence data. A real app might dynamically create geofences based on
* the user's location.
*/
private void populateGeofenceList() {
for (Map.Entry<String, LatLng> entry : Constants.BAY_AREA_LANDMARKS.entrySet()) {
mGeofenceList.add(new Geofence.Builder()
// Set the request ID of the geofence. This is a string to identify this
// geofence.
.setRequestId(entry.getKey())
// Set the circular region of this geofence.
.setCircularRegion(
entry.getValue().latitude,
entry.getValue().longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
// Set the expiration duration of the geofence. This geofence gets automatically
// removed after this period of time.
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
// Set the transition types of interest. Alerts are only generated for these
// transition. We track entry and exit transitions in this sample.
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
// Create the geofence.
.build());
}
}
/**
* Ensures that only one button is enabled at any time. The Add Geofences button is enabled
* if the user hasn't yet added geofences. The Remove Geofences button is enabled if the
* user has added geofences.
*/
private void setButtonsEnabledState() {
if (getGeofencesAdded()) {
mAddGeofencesButton.setEnabled(false);
mRemoveGeofencesButton.setEnabled(true);
openMonitoringButton.setEnabled(true);
} else {
mAddGeofencesButton.setEnabled(true);
mRemoveGeofencesButton.setEnabled(false);
openMonitoringButton.setEnabled(false);
}
}
public void openMonitoring(View view) {
Intent i = new Intent(SetGeofence.this, Monitoring.class);
startActivity(i);
}
/**
* Shows a {@link Snackbar} using {@code text}.
*
* @param text The Snackbar text.
*/
private void showSnackbar(final String text) {
View container = findViewById(android.R.id.content);
if (container != null) {
Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
}
}
/**
* Shows a {@link Snackbar}.
*
* @param mainTextStringId The id for the string resource for the Snackbar text.
* @param actionStringId The text of the action item.
* @param listener The listener associated with the Snackbar action.
*/
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(
findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
/**
* Returns true if geofences were added, otherwise false.
*/
private boolean getGeofencesAdded() {
return PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
Constants.GEOFENCES_ADDED_KEY, false);
}
/**
* Stores whether geofences were added ore removed in {SharedPreferences };
*
* @param added Whether geofences were added or removed.
*/
private void updateGeofencesAdded(boolean added) {
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putBoolean(Constants.GEOFENCES_ADDED_KEY, added)
.apply();
}
/**
* Performs the geofencing task that was pending until location permission was granted.
*/
private void performPendingGeofenceTask() {
if (mPendingGeofenceTask == PendingGeofenceTask.ADD) {
addGeofences();
} else if (mPendingGeofenceTask == PendingGeofenceTask.REMOVE) {
removeGeofences();
}
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
// Provide an additional rationale to the user. This would happen if the user denied the
// request previously, but didn't check the "Don't ask again" checkbox.
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
showSnackbar(R.string.permission_rationale, android.R.string.ok,
new View.OnClickListener() {
@Override
public void onClick(View view) {
// Request permission
ActivityCompat.requestPermissions(SetGeofence.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
});
} else {
Log.i(TAG, "Requesting permission");
// Request permission. It's possible this can be auto answered if device policy
// sets the permission in a given state or the user denied the permission
// previously and checked "Never ask again".
ActivityCompat.requestPermissions(SetGeofence.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted.");
performPendingGeofenceTask();
} else {
// Permission denied.
// Notify the user via a SnackBar that they have rejected a core permission for the
// app, which makes the Activity useless. In a real app, core permissions would
// typically be best requested during a welcome-screen flow.
// Additionally, it is important to remember that a permission might have been
// rejected without asking the user for permission (device policy or "Never ask
// again" prompts). Therefore, a user interface affordance is typically implemented
// when permissions are denied. Otherwise, your app could appear unresponsive to
// touches or interactions which have required permissions.
showSnackbar(R.string.permission_denied_explanation, R.string.settings,
new View.OnClickListener() {
@Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
mPendingGeofenceTask = PendingGeofenceTask.NONE;
}
}
}
}
非常感谢!
onHandleIntent
on GeofenceTransitionsIntentService
应在您的地理围栏为 entered/exited 时执行。 Post 你在该方法中的代码