private void updateSolution(int state) {
   logger.info("Update Solution");
   currentState = state;
   if ((System.currentTimeMillis() - lastFixTimestamp) > 3000) {
     hasFix = false;
   }
   // locationUpdated(locationManager, locationManager.getLastKnownLocation(provider), true);
   if (state == LocationProvider.OUT_OF_SERVICE) {
     if (receiverList != null) {
       receiverList.receiveStatus(LocationMsgReceiver.STATUS_OFF, 0);
       receiverList.receiveMessage(
           Locale.get("androidlocationinput.ProviderStopped") /*provider stopped*/);
     }
     // some devices, e.g. Samsung Galaxy Note will claim LocationProvider.AVAILABLE
     // even when there's no fix, so use a timestamp to detect
   } else if (state == LocationProvider.TEMPORARILY_UNAVAILABLE || !hasFix) {
     if (receiverList != null) {
       receiverList.receiveStatus(LocationMsgReceiver.STATUS_NOFIX, numSatellites);
     }
   } else if (state == LocationProvider.AVAILABLE || hasFix) {
     if (receiverList != null) {
       receiverList.receiveStatus(LocationMsgReceiver.STATUS_ON, numSatellites);
     }
   }
 }
  /**
   * Initializes LocationProvider uses default criteria
   *
   * @throws Exception
   */
  void createLocationProvider() {
    logger.trace("enter createLocationProvider()");
    if (locationManager == null) {
      locationManager =
          (LocationManager) MidletBridge.instance.getSystemService(Context.LOCATION_SERVICE);
      // try out different locationprovider criteria combinations, the
      // ones with maximum features first
      for (int i = 0; i <= 3; i++) {
        try {
          Criteria criteria = new Criteria();
          switch (i) {
            case 0:
              criteria.setAccuracy(Criteria.ACCURACY_FINE);
              criteria.setAltitudeRequired(true);
              criteria.setBearingRequired(true);
              criteria.setSpeedRequired(true);
              break;
            case 1:
              criteria.setAccuracy(Criteria.ACCURACY_FINE);
              criteria.setBearingRequired(true);
              criteria.setSpeedRequired(true);
              break;
            case 2:
              criteria.setAccuracy(Criteria.ACCURACY_FINE);
              criteria.setAltitudeRequired(true);
          }
          provider = locationManager.getBestProvider(criteria, true);
          if (provider != null) {
            logger.info("Chosen location manager:" + locationManager);
            savedCriteria = criteria;
            break; // we are using this criteria
          }
        } catch (Exception e) {
          logger.exception(
              Locale.get(
                  "androidlocationinput.unexpectedExceptioninLocProv") /*unexpected exception while probing LocationManager criteria.*/,
              e);
        }
      }
      if (locationManager != null && provider != null) {
        try {
          locationManager.requestLocationUpdates(provider, 0, 0, this);
          locationManager.addGpsStatusListener(this);
          locationManager.addNmeaListener(this);
        } catch (Exception e) {
          logger.fatal("requestLocationUpdates fail: " + e.getMessage());

          receiverList.receiveStatus(LocationMsgReceiver.STATUS_SECEX, 0);
          locationManager = null;
        }
        if (locationManager != null) {
          // FIXME
          updateSolution(LocationProvider.TEMPORARILY_UNAVAILABLE);
        }

      } else {
        receiverList.locationDecoderEnd(
            Locale.get("androidlocationinput.nointprovider") /*no internal location provider*/);
        // #debug info
        logger.info("Cannot create LocationProvider for criteria.");
      }
    }
    // #debug
    logger.trace("exit createLocationProvider()");
  }