当您走进地理围栏时如何祝酒一条简单的消息?
How to toast a simple message when you walk into a Geofence?
所以我对地理围栏完全陌生,我遵循了以下关于设置地理围栏的教程:http://io2015codelabs.appspot.com/codelabs/geofences#4 .
代码 运行,但是当我走进地理围栏时什么也没有发生...当我进入或离开地理围栏时我该如何敬酒?我的代码与指南中的完全一样。所以我希望你们能帮我举个例子。我
这里是地理围栏class:
public class GeoFence extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
ResultCallback<Status>
{
protected ArrayList<Geofence> mGeofenceList;
protected GoogleApiClient mGoogleApiClient;
private Button mAddGeofencesButton;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geo_fence);
mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
// Empty list for storing geofences.
mGeofenceList = new ArrayList<Geofence>();
// Get the geofences used. Geofence data is hard coded in this sample.
populateGeofenceList();
// Kick off the request to build GoogleApiClient.
buildGoogleApiClient();
}
public void populateGeofenceList() {
for (Map.Entry<String, LatLng> entry : Constants.LANDMARKS.entrySet()) {
mGeofenceList.add(new Geofence.Builder()
.setRequestId(entry.getKey())
.setCircularRegion(
entry.getValue().latitude,
entry.getValue().longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void addGeofencesButtonHandler(View view) {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, "Google API Client not connected!", Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(this); // Result processed in onResult().
} catch (SecurityException securityException) {
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
}
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GTIS.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling addgeoFences()
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// Do something with result.getErrorCode());
}
@Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
@Override
protected void onStart() {
super.onStart();
if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
public void onResult(Status status)
{
if (status.isSuccess()) {
Toast.makeText(
this,
"Geofences Added",
Toast.LENGTH_SHORT
).show();
} else {
Toast.makeText(this,"No geo fence :(",Toast.LENGTH_SHORT).show();
}
}
}
这是 GeofenceT运行sitionsIntentService class
public class GTIS extends IntentService
{
protected static final String TAG = "GeofenceTransitionsIS";
public GTIS() {
super(TAG); // use TAG to name the IntentService worker thread
}
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event.hasError()) {
Log.e(TAG, "GeofencingEvent Error: " + event.getErrorCode());
String description = getGeofenceTransitionDetails(event);
sendNotification(description);
return;
}
}
private static String getGeofenceTransitionDetails(GeofencingEvent event) {
String transitionString =
GeofenceStatusCodes.getStatusCodeString(event.getGeofenceTransition());
List triggeringIDs = new ArrayList();
for (Geofence geofence : event.getTriggeringGeofences()) {
triggeringIDs.add(geofence.getRequestId());
}
return String.format("%s: %s", transitionString, TextUtils.join(", ", triggeringIDs));
}
private void sendNotification(String notificationDetails) {
// Create an explicit content Intent that starts MainActivity.
Intent notificationIntent = new Intent(getApplicationContext(), Geofence.class);
// Get a PendingIntent containing the entire back stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(GeoFence.class).addNextIntent(notificationIntent);
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.setColor(Color.RED)
.setContentTitle(notificationDetails)
.setContentText("Click notification to return to App")
.setContentIntent(notificationPendingIntent)
.setAutoCancel(true);
// Fire and notify the built Notification.
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
}
这是我的常量class:
public class Constants
{
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = 12 * 60 * 60 * 1000;
public static final float GEOFENCE_RADIUS_IN_METERS = 20;
public static final HashMap<String, LatLng> LANDMARKS = new HashMap<String, LatLng>();
static {
// San Francisco International Airport.
LANDMARKS.put("Westwood", new LatLng(34.067313, -118.461164)); //34.065767, -118.459658 LANDMARKS.put("Westwood", new LatLng(34.065767, -118.459658));
// Googleplex.
LANDMARKS.put("Japantown", new LatLng(37.785281,-122.4296384));
// Test
LANDMARKS.put("SFO", new LatLng(37.621313,-122.378955));
}
}
指南中的代码显示 Notification
而不是 Toast
。它不适合你,因为你在 if(event.hasError())
语句中调用 sendNotification()
,在你的情况下没有触发,因为没有错误发生
您需要做的是:
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event.hasError()) {
Log.e(TAG, "GeofencingEvent Error: " + event.getErrorCode());
}
String description = getGeofenceTransitionDetails(event);
sendNotification(description);
}
同样,由于以下原因,此代码将显示 Notification
,这比实际应用中的 Toast
更有意义:
- 您的应用甚至可能在 Geofence 转换时未处于活动状态,并且突然出现的 Toast 对用户来说可能看起来很奇怪。
- 通知允许您显示更多信息(标题和文本)并可能直接返回到您的应用程序
- 它让用户有机会在方便时阅读和关闭它
如果您仍然想显示 Toast
,您应该像在 Activity
中那样做(IntentService
是 Context
也是):
Toast.makeText(this, description, Toast.LENGTH_LONG).show();
所以我对地理围栏完全陌生,我遵循了以下关于设置地理围栏的教程:http://io2015codelabs.appspot.com/codelabs/geofences#4 .
代码 运行,但是当我走进地理围栏时什么也没有发生...当我进入或离开地理围栏时我该如何敬酒?我的代码与指南中的完全一样。所以我希望你们能帮我举个例子。我
这里是地理围栏class:
public class GeoFence extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
ResultCallback<Status>
{
protected ArrayList<Geofence> mGeofenceList;
protected GoogleApiClient mGoogleApiClient;
private Button mAddGeofencesButton;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geo_fence);
mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
// Empty list for storing geofences.
mGeofenceList = new ArrayList<Geofence>();
// Get the geofences used. Geofence data is hard coded in this sample.
populateGeofenceList();
// Kick off the request to build GoogleApiClient.
buildGoogleApiClient();
}
public void populateGeofenceList() {
for (Map.Entry<String, LatLng> entry : Constants.LANDMARKS.entrySet()) {
mGeofenceList.add(new Geofence.Builder()
.setRequestId(entry.getKey())
.setCircularRegion(
entry.getValue().latitude,
entry.getValue().longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void addGeofencesButtonHandler(View view) {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, "Google API Client not connected!", Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(this); // Result processed in onResult().
} catch (SecurityException securityException) {
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
}
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GTIS.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling addgeoFences()
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// Do something with result.getErrorCode());
}
@Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
@Override
protected void onStart() {
super.onStart();
if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
public void onResult(Status status)
{
if (status.isSuccess()) {
Toast.makeText(
this,
"Geofences Added",
Toast.LENGTH_SHORT
).show();
} else {
Toast.makeText(this,"No geo fence :(",Toast.LENGTH_SHORT).show();
}
}
}
这是 GeofenceT运行sitionsIntentService class
public class GTIS extends IntentService
{
protected static final String TAG = "GeofenceTransitionsIS";
public GTIS() {
super(TAG); // use TAG to name the IntentService worker thread
}
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event.hasError()) {
Log.e(TAG, "GeofencingEvent Error: " + event.getErrorCode());
String description = getGeofenceTransitionDetails(event);
sendNotification(description);
return;
}
}
private static String getGeofenceTransitionDetails(GeofencingEvent event) {
String transitionString =
GeofenceStatusCodes.getStatusCodeString(event.getGeofenceTransition());
List triggeringIDs = new ArrayList();
for (Geofence geofence : event.getTriggeringGeofences()) {
triggeringIDs.add(geofence.getRequestId());
}
return String.format("%s: %s", transitionString, TextUtils.join(", ", triggeringIDs));
}
private void sendNotification(String notificationDetails) {
// Create an explicit content Intent that starts MainActivity.
Intent notificationIntent = new Intent(getApplicationContext(), Geofence.class);
// Get a PendingIntent containing the entire back stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(GeoFence.class).addNextIntent(notificationIntent);
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.setColor(Color.RED)
.setContentTitle(notificationDetails)
.setContentText("Click notification to return to App")
.setContentIntent(notificationPendingIntent)
.setAutoCancel(true);
// Fire and notify the built Notification.
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
}
这是我的常量class:
public class Constants
{
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = 12 * 60 * 60 * 1000;
public static final float GEOFENCE_RADIUS_IN_METERS = 20;
public static final HashMap<String, LatLng> LANDMARKS = new HashMap<String, LatLng>();
static {
// San Francisco International Airport.
LANDMARKS.put("Westwood", new LatLng(34.067313, -118.461164)); //34.065767, -118.459658 LANDMARKS.put("Westwood", new LatLng(34.065767, -118.459658));
// Googleplex.
LANDMARKS.put("Japantown", new LatLng(37.785281,-122.4296384));
// Test
LANDMARKS.put("SFO", new LatLng(37.621313,-122.378955));
}
}
指南中的代码显示 Notification
而不是 Toast
。它不适合你,因为你在 if(event.hasError())
语句中调用 sendNotification()
,在你的情况下没有触发,因为没有错误发生
您需要做的是:
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event.hasError()) {
Log.e(TAG, "GeofencingEvent Error: " + event.getErrorCode());
}
String description = getGeofenceTransitionDetails(event);
sendNotification(description);
}
同样,由于以下原因,此代码将显示 Notification
,这比实际应用中的 Toast
更有意义:
- 您的应用甚至可能在 Geofence 转换时未处于活动状态,并且突然出现的 Toast 对用户来说可能看起来很奇怪。
- 通知允许您显示更多信息(标题和文本)并可能直接返回到您的应用程序
- 它让用户有机会在方便时阅读和关闭它
如果您仍然想显示 Toast
,您应该像在 Activity
中那样做(IntentService
是 Context
也是):
Toast.makeText(this, description, Toast.LENGTH_LONG).show();