【问题标题】:multiple alarms calling same service多个警报调用相同的服务
【发布时间】:2015-09-15 12:01:30
【问题描述】:

我有多个警报调用广播意图,而广播意图又调用位置服务。这个想法是在不同的时间获得位置。位置服务需要一些时间才能返回位置,之后它会关闭。 我想知道如果 2 个警报同时调用这个公共位置服务,或者说警报 1 已经调用了位置服务,而在第二个警报 2 也称为位置服务,因为我已经读过服务只有 1 个实例,会发生什么情况。

还有什么是处理我上面提到的案件的最佳方法?

Intent intent = new Intent(context, NotificationView.class);
 PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    alarmManager.set(AlarmManager.RTC_WAKEUP, dateTime.getTimeInMillis(), pendingIntent);

在我的 NotificationView.class 我调用服务

Intent serviceIntent = new Intent(context,MyLocationService.class);
    context.startService(serviceIntent); //start service for get location

在通过这个待定意图调用同一服务的某些秒的差异内可以安排多个警报。

【问题讨论】:

  • 发布您的代码。我认为问题是你的pendingIntents应该包含不同的requestCodes,当你把它们放到Broadcast中时
  • @АндройдАндройд 已更新。此外,即使更改请求代码,服务也将保持不变?通过单独的未决意图调用。这将如何处理?

标签: android service location alarmmanager


【解决方案1】:

是的,你说得对。我展示了我的代码,其中我的请求代码是 i 变量。你可以为你改变它

public static void setAlarmReceiver(Context context, ArrayList<CheckPoint> checkPoints) {

        clearAlarmReceiver(context);

        if (checkPoints.size() == 0)
            return;

        int i = 0;
        for (CheckPoint checkPoint : checkPoints) {
            Intent intent = new Intent(context, CheckAlarmReceiver.class);
            intent.putExtra("checkPoint", checkPoint);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, i, intent, PendingIntent.FLAG_CANCEL_CURRENT);
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(getDay(checkPoint.getDate())));
            calendar.set(Calendar.MONTH, Integer.valueOf(getMonth(checkPoint.getDate())) - 1);
            calendar.set(Calendar.YEAR, Integer.valueOf(getYear(checkPoint.getDate())));
            calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(getHour(checkPoint.getCheckInTime())));
            calendar.set(Calendar.MINUTE, Integer.valueOf(getMinute(checkPoint.getCheckInTime())));
            calendar.set(Calendar.SECOND, 0);
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            if (android.os.Build.VERSION.SDK_INT >= 19) {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
            } else {
                alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
            }

            i++;
        }
    }

【讨论】:

  • 还要注意alarmManager.setExact和alarmManager.set
  • 我知道这件事,但如果所有这些单独的警报同时调用一个公共服务怎么办。服务将如何处理?是否会创建单独的实例,因为我认为不允许这样做?
【解决方案2】:

在我看来,最好的解决方案是创建辅助类,例如缓存位置并防止对服务的额外调用。

public class LocationHelper {
  public static AbstractMap.SimpleEntry<Long, Location> cache = null; //location stored here
  public static int expiryTime = 5000; // 5 seconds for example

  private static boolean requested = false;

  private static List<LocationListener> callbacks = new ArrayList<>();// request heap

  public static void getLocation(LocationManager lm, LocationListener ll){
    Long currentTimeStamp = getTimeStamp();
    final LocationListener mLocationListener = new LocationListener() {
       @Override
       public void onLocationChanged(final Location location) {
         cache = new AbstractMap.SimpleEntry<>(getTimeStamp(), location);

         synchronized(LocationHelper.class){
           for(LocationListener loclist : callbacks){
             loclist.onLocationChanged(location); // call each listener
           }
           callbacks.clear(); 
           requested = false;
         }
       }
    };
    if (cache != null && currentTimeStamp - cache.getKey() < expiryTime){
      ll.onLocationChanged(cache.getValue());
    } else {
       if(!requested){
         synchronized(LocationHelper.class){ // synchronize class to prevent thread collision and additional request
           if(!requested){
             lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_REFRESH_TIME, LOCATION_REFRESH_DISTANCE, mLocationListener);
             requested = true;
           }
         }
       } else {
         synchronized(LocationHelper.class){
           callbacks.add(ll);
         }
       }
    }
  }

  public static Long getTimeStamp(){/*some code here*/}
}

这个解决方案有点复杂,但应该可以工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多