2016-04-25 100 views
0

大家好我在我的android应用程序中实现geofencing功能来发送toast通知。事情是当我在里面(我在做栅栏的时候)我创建了一个栅栏,然后意图被解雇了,但是当我试图通过重新输入位置意图再次触发事件在不触发这里是我的代码Geofencing Intent Not Firing

protected override void OnHandleIntent (Intent intent) 
    { 
     Intent broadcastIntent = new Intent(); 


     var geofencingEvent = GeofencingEvent.FromIntent (intent); 
     if (geofencingEvent.HasError) { 
      var errorMessage = GeofenceErrorMessages.GetErrorString (this, geofencingEvent.ErrorCode); 
      Log.Error (TAG, errorMessage); 
      return; 
     } 

     int geofenceTransition = geofencingEvent.GeofenceTransition; 

     if (geofenceTransition == Geofence.GeofenceTransitionEnter || 
      geofenceTransition == Geofence.GeofenceTransitionExit) { 
       Toast.MakeText(this, "Service Started", ToastLength.Long).Show(); 

      IList<IGeofence> triggeringGeofences = geofencingEvent.TriggeringGeofences; 

      string geofenceTransitionDetails = GetGeofenceTransitionDetails (this, geofenceTransition, triggeringGeofences); 

      SendNotification (geofenceTransitionDetails); 
      Log.Info (TAG, geofenceTransitionDetails); 
     } else { 
      // Log the error. 
      Log.Error (TAG, GetString (Resource.String.geofence_transition_invalid_type, new [] { new Java.Lang.Integer (geofenceTransition) })); 
     } 
    } 

    string GetGeofenceTransitionDetails (Context context, int geofenceTransition, IList<IGeofence> triggeringGeofences) 
    { 
     string geofenceTransitionString = GetTransitionString (geofenceTransition); 

     var triggeringGeofencesIdsList = new List<string>(); 
     foreach (IGeofence geofence in triggeringGeofences) { 
      triggeringGeofencesIdsList.Add (geofence.RequestId); 
     } 
     var triggeringGeofencesIdsString = string.Join (", ", triggeringGeofencesIdsList); 

     return geofenceTransitionString + ": " + triggeringGeofencesIdsString; 
    } 

    void SendNotification (string notificationDetails) 
    { 
     var notificationIntent = new Intent (ApplicationContext, typeof(MainActivity)); 

     var stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create (this); 
     stackBuilder.AddParentStack (Java.Lang.Class.FromType (typeof(MainActivity))); 
     stackBuilder.AddNextIntent (notificationIntent); 

     var notificationPendingIntent = stackBuilder.GetPendingIntent (0, (int)PendingIntentFlags.UpdateCurrent); 

     var builder = new NotificationCompat.Builder (this); 
     builder.SetSmallIcon (Resource.Drawable.icon) 
      .SetLargeIcon (BitmapFactory.DecodeResource (Resources, Resource.Drawable.icon)) 
      .SetColor (Color.Red) 
      .SetContentTitle (notificationDetails) 
      .SetContentText (GetString (Resource.String.geofence_transition_notification_text)) 
      .SetContentIntent (notificationPendingIntent); 

     builder.SetAutoCancel (true); 

     var mNotificationManager = (NotificationManager)GetSystemService (Context.NotificationService); 
     mNotificationManager.Notify (0, builder.Build()); 
    } 

    string GetTransitionString (int transitionType) 
    { 
     switch (transitionType) { 
     case Geofence.GeofenceTransitionEnter: 
      return GetString (Resource.String.geofence_transition_entered); 
     case Geofence.GeofenceTransitionExit: 
      return GetString (Resource.String.geofence_transition_exited); 
     default: 
      return GetString (Resource.String.unknown_geofence_transition); 
     } 
    } 

,我的主要活动是

{ 
    protected const string TAG = "creating-and-monitoring-geofences"; 
    protected GoogleApiClient mGoogleApiClient; 
    protected IList<IGeofence> mGeofenceList; 
    bool mGeofencesAdded; 
    PendingIntent mGeofencePendingIntent; 
    ISharedPreferences mSharedPreferences; 
    Button mAddGeofencesButton; 
    Button mRemoveGeofencesButton; 

    protected override void OnCreate (Bundle savedInstanceState) 
    { 
     base.OnCreate (savedInstanceState); 
     SetContentView (Resource.Layout.main_activity); 

     mAddGeofencesButton = FindViewById<Button> (Resource.Id.add_geofences_button); 
     mRemoveGeofencesButton = FindViewById<Button> (Resource.Id.remove_geofences_button); 

     mAddGeofencesButton.Click += AddGeofencesButtonHandler; 
     mRemoveGeofencesButton.Click += RemoveGeofencesButtonHandler; 
     mGeofenceList = new List<IGeofence>(); 
     mGeofencePendingIntent = null; 

     mSharedPreferences = GetSharedPreferences (Constants.SHARED_PREFERENCES_NAME, 
      FileCreationMode.Private); 

     mGeofencesAdded = mSharedPreferences.GetBoolean (Constants.GEOFENCES_ADDED_KEY, false); 

     SetButtonsEnabledState(); 
     PopulateGeofenceList(); 
     BuildGoogleApiClient(); 
    } 

    protected void BuildGoogleApiClient() 
    { 
     mGoogleApiClient = new GoogleApiClient.Builder (this) 
      .AddConnectionCallbacks (this) 
      .AddOnConnectionFailedListener (this) 
      .AddApi (LocationServices.API) 
      .Build(); 
    } 
    private IntentFilter mIntentFilter; 

    protected override void OnResume() 
    { 
     base.OnResume(); 
     mGoogleApiClient.Connect(); 


    } 
    protected override void OnStart() 
    { 
     base.OnStart(); 
     mGoogleApiClient.Connect(); 
    } 

    protected override void OnStop() 
    { 
     base.OnStop(); 
    // mGoogleApiClient.Disconnect(); 
    } 

    public void OnConnected (Bundle connectionHint) 
    { 
     Log.Info (TAG, "Connected to GoogleApiClient"); 
    } 

    public void OnConnectionSuspended (int cause) 
    { 
     Log.Info (TAG, "Connection suspended"); 
    } 

    public void OnConnectionFailed (Android.Gms.Common.ConnectionResult result) 
    { 
     Log.Info (TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.ErrorCode); 
    } 

    GeofencingRequest GetGeofencingRequest() 
    { 
     var builder = new GeofencingRequest.Builder(); 
     builder.SetInitialTrigger (GeofencingRequest.InitialTriggerEnter); 
     builder.AddGeofences (mGeofenceList); 

     return builder.Build(); 
    } 

    public async void AddGeofencesButtonHandler (object sender, EventArgs e) 
    { 
     if (!mGoogleApiClient.IsConnected) { 
      Toast.MakeText (this, GetString (Resource.String.not_connected), ToastLength.Short).Show(); 
      return; 
     } 

     try { 
      var status = await LocationServices.GeofencingApi.AddGeofencesAsync (mGoogleApiClient, GetGeofencingRequest(), 
       GetGeofencePendingIntent()); 
      HandleResult (status); 
     } catch (SecurityException securityException) { 
      LogSecurityException(securityException); 
     } 
    } 

    public async void RemoveGeofencesButtonHandler (object sender, EventArgs e) 
    { 
     if (!mGoogleApiClient.IsConnected) { 
      Toast.MakeText (this, GetString(Resource.String.not_connected), ToastLength.Short).Show(); 
      return; 
     } 
     try { 
      var status = await LocationServices.GeofencingApi.RemoveGeofencesAsync (mGoogleApiClient, 
       GetGeofencePendingIntent()); 
      HandleResult (status); 
     } catch (SecurityException securityException) { 
      LogSecurityException (securityException); 
     } 
    } 

    void LogSecurityException (SecurityException securityException) 
    { 
     Log.Error (TAG, "Invalid location permission. " + 
      "You need to use ACCESS_FINE_LOCATION with geofences", securityException); 
    } 

    public void HandleResult (Statuses status) 
    { 
     if (status.IsSuccess) { 
      mGeofencesAdded = !mGeofencesAdded; 
      var editor = mSharedPreferences.Edit(); 
      editor.PutBoolean (Constants.GEOFENCES_ADDED_KEY, mGeofencesAdded); 
      editor.Commit(); 

      SetButtonsEnabledState(); 

      Toast.MakeText (
       this, 
       GetString (mGeofencesAdded ? Resource.String.geofences_added : 
        Resource.String.geofences_removed), 
       ToastLength.Short 
      ).Show(); 
     } else { 
      var errorMessage = GeofenceErrorMessages.GetErrorString (this, 
       status.StatusCode); 
      Log.Error (TAG, errorMessage); 
     } 
    } 

    PendingIntent GetGeofencePendingIntent() 
    { 
     if (mGeofencePendingIntent != null) { 
      return mGeofencePendingIntent; 
     } 
     //var intent = new Intent(this, typeof(Test)); 
     //SendBroadcast(intent); 
     //return PendingIntent.GetBroadcast(this, 0, intent, PendingIntentFlags.UpdateCurrent); 

     var intent = new Intent(this, typeof(GeofenceTransitionsIntentService)); 
     //SendBroadcast(intent); 
     return PendingIntent.GetService(this, 0, intent, PendingIntentFlags.UpdateCurrent); 

    } 

    public void PopulateGeofenceList() 
    { 
     foreach (var entry in Constants.BAY_AREA_LANDMARKS) { 
      mGeofenceList.Add (new GeofenceBuilder() 
       .SetRequestId (entry.Key) 
       .SetCircularRegion (
        entry.Value.Latitude, 
        entry.Value.Longitude, 
        Constants.GEOFENCE_RADIUS_IN_METERS 
       ) 
       .SetExpirationDuration (Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) 
       .SetTransitionTypes (Geofence.GeofenceTransitionEnter | 
        Geofence.GeofenceTransitionExit) 
       .Build()); 
     } 
    } 

    void SetButtonsEnabledState() 
    { 
     if (mGeofencesAdded) { 
      mAddGeofencesButton.Enabled = false; 
      mRemoveGeofencesButton.Enabled = true; 
     } else { 
      mAddGeofencesButton.Enabled = true; 
      mRemoveGeofencesButton.Enabled = false; 
     } 
    } 
} 

}

我也试过制作一个广播接收器,但它对我没有太大的帮助

+0

你如何测试你的GeoFence。如果您使用的是Google的API,则必须通过模拟位置提供者以现实的方式将其当前位置以逼真的方式移入和移出围栏,以便从100km以外的区域跳出,并且在隔离区之后一秒钟火。如果我以步行或者外行的速度从外部移动到内部(并且让它坐在内部进行几次呼叫),那么它会发射。 –

+0

@MorrisonChang其实我创造了一个距离我目前位置100米的围栏,我在3分钟内走向围栏是不够的?还是应该更多? –

+0

@MorrisonChang是否有任何可靠的地理围栏API?而不是谷歌API快速工作? –

回答

0

我看到你的代码看起来和你从谷歌开发者页面中拉出来的样本完全一样,而且是许多人开始使用得最多的那个。我自己也遇到了准确性问题以及与此相关的围栏过渡问题。我读过手动添加上一个位置请求包(LocationManager)的实例,并明确指定GPS作为高度更新模式下的提供者可以使其更加准确。这就是我现在的工作方式。您也可以尝试使栅栏的半径更大,这样您就可以考虑到最低的Wi-Fi精度,据说大约在50米左右,而不考虑漂移。

+0

我使用广播接收器而不是意图服务,我的结果也变得更好,我设定的半径也是最小的100米,所以也帮助顺道一提,我发布了很长的路要回答谢谢你回答 –

+0

很酷,你也修复了它...继续编码! :) –