My location is null with the service turned off

/**

  • @file ServicioEscuharBeacons.java
  • @brief Este archivo contiene la implementación del servicio para escuchar beacons.
    */

/**

  • @brief Servicio para escuchar beacons BLE (Bluetooth Low Energy).
    */
    public class ServicioEscuharBeacons extends Service {

    private double distanciaPromedio = -1.0;
    private int muestras = 0;
    private final int NUM_MUESTRAS_PROMEDIO = 10;
    public static final String ACTION_SOLICITAR_PERMISOS_BLUETOOTH = “SOLICITAR_PERMISOS_BLUETOOTH”;
    public static final String ACTION_SOLICITAR_PERMISOS_UBICACION = “SOLICITAR_PERMISOS_UBICACION”;
    public static final int CODIGO_PETICION_PERMISO_BLUETOOTH = 1;
    public static final int CODIGO_PETICION_PERMISO_UBICACION = 2;

    private Handler handler = new Handler();
    private PowerManager.WakeLock mWakeLock;
    private Runnable obtenerUbicacionRunnable;
    private static final double UMBRAL_CAMBIO = 2;
    private ControladorBLE controladorBLE;
    private String dispositivoBuscado;
    private int ID_AIRSENSE = 1;

    private static final long LOCATION_UPDATE_INTERVAL = 10000; // 10 seconds interval
    private int ID_CO2 = 2;
    NotificationManager mNotificationManager;
    private static int notificationId = 1;

    private FusedLocationProviderClient fusedLocationClient;

    @Override
    public void onCreate() {
    super.onCreate();
    controladorBLE = new ControladorBLE(this);
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

     obtenerUbicacionRunnable = new Runnable() {
         @Override
         public void run() {
             obtenerLatitudLongitud();
             handler.postDelayed(this , LOCATION_UPDATE_INTERVAL);
         }
     };
    
     handler.postDelayed(obtenerUbicacionRunnable , LOCATION_UPDATE_INTERVAL);
    
     buscarEsteDispositivoBTLE();
    
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         NotificationChannel channel1 = new NotificationChannel("1" , "Conexion AirSense" , NotificationManager.IMPORTANCE_HIGH);
         channel1.enableVibration(true);
         channel1.setShowBadge(true);
    
         NotificationChannel channel2 = new NotificationChannel("2" , "Alertas CO2" , NotificationManager.IMPORTANCE_HIGH);
         channel2.enableVibration(true);
         channel2.setShowBadge(true);
    
         NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
         notificationManager.createNotificationChannel(channel1);
         notificationManager.createNotificationChannel(channel2);
     }
    
     // Configurar notificación persistente
     setupPersistentNotification("Has superado los limites oficiales" , "Nivel alto de CO2" , "2" , ID_CO2);
    

    }

    private void setupPersistentNotification(String titulo , String text , String canal , int id) {
    Notification notification = crearNotificacion(titulo , text , canal , id);
    notification.visibility = Notification.VISIBILITY_PUBLIC;

     // Modificación aquí
     startForeground(id , notification);
    

    }

    private void mostrarNotificacion(Notification notification , int id) {
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(id , notification);

    }

    private void buscarEsteDispositivoBTLE() {
    controladorBLE.buscarEsteDispositivoBTLE(dispositivoBuscado , new BLECallback() {
    @Override
    public void onSuccess(String valor_medicion , String id_medicion , String nombre , double Rssi , double txpower) {
    double distancia = Double.parseDouble(String.valueOf(calcularDistancia(txpower , Rssi , 2)));
    double distanciaPromedio = calcularPromedio(distancia);

             if (distanciaPromedio < 0 || Math.abs(distancia - distanciaPromedio) < UMBRAL_CAMBIO) {
    
    
                 Intent intent = new Intent("airsense-conectado");
                 intent.putExtra("distancia" , String.format("%.2f" , distanciaPromedio));
                 intent.putExtra("valor_medicion" , valor_medicion);
                 intent.putExtra("id_medicion" , id_medicion);
                 LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
             }
         }
     });
    

    }

    public void obtenerLatitudLongitud() {
    if (ActivityCompat.checkSelfPermission(this , android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
    ActivityCompat.checkSelfPermission(this , Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    return;
    }

     fusedLocationClient.getCurrentLocation(LocationRequest.PRIORITY_HIGH_ACCURACY , null)
             .addOnSuccessListener(TaskExecutors.MAIN_THREAD , new OnSuccessListener<Location>() {
                 @Override
                 public void onSuccess(Location location) {
                     if (location != null) {
                         double latitud = location.getLatitude();
                         double longitud = location.getLongitude();
    
                         Intent latitud1 = new Intent("LATITUD");
                         latitud1.putExtra("latitud" , latitud);
                         latitud1.putExtra("longitud" , longitud);
                         LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(latitud1);
                     } else {
                         Log.e("MiServicio" , "Ubicación nula");
                         Toast.makeText(getApplicationContext() , "Ubicación nula" , Toast.LENGTH_SHORT).show();
                     }
                 }
             })
             .addOnFailureListener(new OnFailureListener() {
                 @Override
                 public void onFailure(@NonNull Exception e) {
                     // Manejar fallo al obtener la ubicación
                     Toast.makeText(getApplicationContext() , "Error al obtener la ubicación" , Toast.LENGTH_SHORT).show();
                     e.printStackTrace();
                 }
             });
    

    }

    @SuppressLint(“InvalidWakeLockTag”)
    @Override
    public int onStartCommand(Intent intent , int flags , int startId) {
    if (intent != null) {
    String action = intent.getAction();
    if (“dispositivoBuscado”.equals(action)) {
    if (intent.getStringExtra(“dispositivoBuscado”) != null) {
    String dispositivoBuscado = intent.getStringExtra(“dispositivoBuscado”);
    this.dispositivoBuscado = dispositivoBuscado;
    }

             // Adquirir WakeLock
             PowerManager mgr = (PowerManager) getSystemService(Context.POWER_SERVICE);
             if (this.mWakeLock == null) {
                 this.mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK , "MyWakeLock");
             }
             if (!this.mWakeLock.isHeld()) {
                 this.mWakeLock.acquire();
             }
    
             obtenerLatitudLongitud();
             buscarEsteDispositivoBTLE();
             controladorBLE.detenerBusquedaDispositivosBTLE();
         }
     }
    
     return Service.START_STICKY;
    

    }

    @Override
    public void onDestroy() {
    handler.removeCallbacks(obtenerUbicacionRunnable);
    controladorBLE.detenerBusquedaDispositivosBTLE();

     NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
     notificationManager.cancel(1);
    
     // Liberar WakeLock
     if (this.mWakeLock != null) {
         if (this.mWakeLock.isHeld()) {
             this.mWakeLock.release();
         }
         this.mWakeLock = null;
     }
    
    
     super.onDestroy();
    

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    return null;
    }

    /**

    • @param titulo Título de la notificación.
    • @return La notificación creada.
    • @brief Crea una notificación para el servicio.
      */

    private Notification crearNotificacion(String titulo , String text , String canal , int id) {
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this , canal)
    .setSmallIcon(R.drawable.logo)
    .setContentTitle(titulo)
    .setContentText(text)
    .setPriority(NotificationCompat.PRIORITY_MAX)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .setColor(Color.rgb(49 , 143 , 169))
    .setOngoing(false);

     Intent notificationIntent = new Intent(this , Home.class);
     PendingIntent pendingIntent;
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
         pendingIntent = PendingIntent.getService(this , id , notificationIntent , PendingIntent.FLAG_IMMUTABLE);
     } else {
         pendingIntent = PendingIntent.getService(this , id , notificationIntent , PendingIntent.FLAG_IMMUTABLE);
     }
     builder.setContentIntent(pendingIntent);
    
     return builder.build();
    

    }

    /**

    • @brief Actualiza la notificación con un nuevo mensaje.
      */
      /private void actualizarNotificacion(String titulo, int id) {
      Notification notification = crearNotificacion(titulo, id);
      NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      notificationManager.notify(id , notification);
      }
      /

    /**

    • @param txPower Potencia de transmisión conocida.
    • @param rssi Intensidad de la señal recibida.
    • @param n Factor de corrección ambiental.
    • @return La distancia calculada en metros.
    • @brief Calcula la distancia entre dos dispositivos usando la potencia de la señal y la intensidad de la señal recibida (RSSI).
      */
      private double calcularDistancia(double txPower , double rssi , double n) {
      if (rssi == 0) {
      return -1.0; // Valor inválido
      }
      return Math.pow(10 , ((txPower – rssi) / (10 * n)));
      }

    /**

    • @param nuevaMuestra El nuevo valor de la muestra.
    • @return El promedio móvil calculado.
    • @brief Calcula el promedio móvil de las últimas muestras
      */
      private double calcularPromedio(double nuevaMuestra) {
      if (muestras < NUM_MUESTRAS_PROMEDIO) {
      // Aún no se han acumulado suficientes muestras, simplemente suma las muestras anteriores y la nueva
      distanciaPromedio = (distanciaPromedio * muestras + nuevaMuestra) / (muestras + 1);
      muestras++;
      } else {
      // Si se han acumulado suficientes muestras, calcula el promedio móvil eliminando la muestra más antigua
      distanciaPromedio = distanciaPromedio + (nuevaMuestra – distanciaPromedio) / NUM_MUESTRAS_PROMEDIO;
      }
      return distanciaPromedio;
      }
      }

Leave a Comment