带有附加功能的地理围栏 PendingIntent

Posted

技术标签:

【中文标题】带有附加功能的地理围栏 PendingIntent【英文标题】:Geofence PendingIntent with extras 【发布时间】:2014-08-25 15:06:46 【问题描述】:

问题来了:

添加地理围栏的服务:

public class GeofenceService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationClient.OnAddGeofencesResultListener, LocationClient.OnRemoveGeofencesResultListener 
     ...

            @Override
                public void onConnected(Bundle bundle) 
                    Log.d(TAG, "onConnected");
                    switch (action)
                        case ADD:
                            Log.d(TAG, "onConnected ADD");
                            locationClient.addGeofences(geofencesToAdd, getPendingIntent(), this);
                            break;
                        case REMOVE:
                            Log.d(TAG, "onConnected REMOVE");
                            locationClient.removeGeofences(geofencesToRemove, this);
                            break;
                    
                

                private PendingIntent getPendingIntent()
                    Intent intent = new Intent().setClass(this, TransitionsIntentService.class);
                    intent.putExtra(EXTRA_DEALS, deals);
                    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                
    ...

如您所见,有 Intent 传递一些数据并启动 TransitionIntentService:

public class TransitionsIntentService extends IntentService 

   ... 
@Override
protected void onHandleIntent(Intent intent) 
        deals = (ArrayList<Deal>) intent.getSerializableExtra(GeofenceService.EXTRA_DEALS); //THIS CAN BE NULL

        int transitionType = LocationClient.getGeofenceTransition(intent);

        List<Geofence> triggeredGeofences = LocationClient.getTriggeringGeofences(intent); //THIS CAN BE NULL
        List<String> triggeredIds = new ArrayList<String>();

        for (Geofence geofence : triggeredGeofences) 
            Log.d("GEO", "onHandle:" + geofence.getRequestId());
            processGeofence(geofence, transitionType);
            triggeredIds.add(geofence.getRequestId());
        

    ...

如果我尝试在 getPendingIntent 方法中放入额外的(...,交易),我会得到 List&lt;Geofence&gt; triggeredGeofences = LocationClient.getTriggeringGeofences(intent) == NULL

如果我不通过额外的一切工作正常。

我怎样才能通过我的额外收入并仍然从LocationClient 获得额外收入?

【问题讨论】:

只有triggeredGeofences为空,还是deals也在onHandleIntent中? 如果我将 Deal 对象作为额外对象传递,则交易不为空。如果我不那么触发Geofences 不为空。另外,我可以将 String 对象作为额外的对象传递,一切都会好起来的。当我尝试传递自己的可序列化交易对象时,问题就出现了 即使我有这个问题,你有没有机会解决它? 【参考方案1】:

我知道这是一个老问题,但我遇到了完全相同的症状和问题。基本上,似乎GeofenceEvent 不能与意图中的Serializable 额外共存。我发现的唯一解决方案是展平可序列化对象并为每个字段使用具有简单数据类型的单独额外对象,如以下简单示例所示:

通过意图传输的对象:

public class MyObject 
  public String stringfield;
  public int intField;

  public MyObject fromIntent(Intent intent) 
    stringField = intent.getStringExtra("stringField");
    intField = intent.getIntExtra("intField", -1);
    return this;
  

  public MyObject toIntent(Intent intent) 
    intent.putExtra("stringField", stringField);
    intent.putExtra("intField", intField);
    return this;
  

创建和填充意图:

MyObject obj = ...;
Intent intent = ...;
myObject.toIntent(intent);

从接收到的意图中提取数据:

Intent intent = ...;
MyObject obj = new MyObject().fromIntent(intent);

这有点麻烦,但这是我让它工作的唯一方法。我现在可以从同一个意图中提取 GeofenceEvent 数据和我的自定义数据。

【讨论】:

【参考方案2】:

似乎GeofenceEvent 不能与意图中的Serializable 额外共存。

我找到的解决方案是让传递对象变成静态。在IntentService类中,直接访问静态对象。

例如,

GeofenceService.java

public class GeofenceService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, ...



     ...

     public static ArrayList<Deal> extraDeals;

     ...


TransitionsIntentService.java

public class TransitionsIntentService extends IntentService 

    ... 

    @Override
    protected void onHandleIntent(Intent intent) 
        ...

        deals = GeofenceService.extraDeals;

        ...
    

    ...


【讨论】:

【参考方案3】:

我不是专家,但这可能对你有帮助

在您的代码中

return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

用这个替换

return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

对于那些查看此内容并在附加到 PendingIntent 之前拥有 .putExtra 方法的人,PendingIntent.FLAG_UPDATE_CURRENT 很重要,因此请在继续使用其他解决方案之前尝试一下。

【讨论】:

以上是关于带有附加功能的地理围栏 PendingIntent的主要内容,如果未能解决你的问题,请参考以下文章

地理围栏 PendingIntent 始终为空

onHandleWork 从未收到来自 pendingintent 地理围栏的意图

地理围栏转换 PendingIntent 被 Android Oreo 上的操作系统阻止

应用程序死机时的地理围栏

在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为啥?

带有模拟位置提供程序的 Android 地理围栏