Compare commits

...

2 Commits

Author SHA1 Message Date
aab826f651 Merge remote-tracking branch 'origin/main' 2026-03-12 10:40:43 +00:00
46076d43d4 implementei um plugin 2026-03-12 10:40:37 +00:00
5 changed files with 155 additions and 1 deletions

View File

@@ -72,4 +72,6 @@ dependencies {
implementation("com.github.bumptech.glide:glide:4.16.0")
annotationProcessor("com.github.bumptech.glide:compiler:4.16.0")
implementation("com.google.firebase:firebase-storage:21.0.1")
implementation("com.google.android.gms:play-services-location:21.0.1")
implementation("com.google.firebase:firebase-database-ktx:20.3.0")
}

View File

@@ -4,7 +4,15 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<application
android:allowBackup="true"
@@ -20,6 +28,12 @@
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyAxen212OKqkfpu1AbWajLGTCTSdRhJWlM" />
<service
android:name=".LocationService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
<activity
android:name=".CriarConta"
android:exported="false" />

View File

@@ -0,0 +1,122 @@
package com.example.pap_findu;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.Priority;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.HashMap;
import java.util.Map;
public class LocationService extends Service {
private FusedLocationProviderClient fusedLocationClient;
private LocationCallback locationCallback;
private DatabaseReference databaseReference;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
// Inicializa o cliente de GPS e a ligação ao Firebase
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
// ATENÇÃO: Substitua "ID_DA_CRIANCA" pelo ID real do utilizador logado no momento
databaseReference = FirebaseDatabase.getInstance().getReference("users/ID_DA_CRIANCA/live_location");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 1. Inicia a Notificação Persistente (Obrigatório para serviços em background)
createNotificationChannel();
Notification notification = new NotificationCompat.Builder(this, "LocationChannel")
.setContentTitle("FindU Ativo")
.setContentText("A monitorizar a localização em tempo real...")
// Substitua ic_launcher pelo ícone da sua app (ex: R.drawable.ic_launcher_foreground)
.setSmallIcon(R.mipmap.ic_launcher)
.build();
startForeground(1, notification);
// 2. Inicia o Rastreamento de GPS
requestLocationUpdates();
return START_STICKY;
}
// Ignora o aviso de permissão porque vamos pedir a permissão na Activity ANTES de iniciar este serviço
@SuppressWarnings("MissingPermission")
private void requestLocationUpdates() {
// Configura a frequência do GPS (ex: a cada 10 segundos)
LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
.setMinUpdateDistanceMeters(5.0f) // Só envia se a pessoa se mover 5 metros (poupa bateria)
.build();
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
for (Location location : locationResult.getLocations()) {
// 3. Envia os dados atualizados para o Firebase Realtime Database
Map<String, Object> locationData = new HashMap<>();
locationData.put("latitude", location.getLatitude());
locationData.put("longitude", location.getLongitude());
locationData.put("last_updated", System.currentTimeMillis());
databaseReference.setValue(locationData);
}
}
};
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
@Override
public void onDestroy() {
super.onDestroy();
// Quando o serviço for desligado, para de usar o GPS para poupar bateria
if (fusedLocationClient != null && locationCallback != null) {
fusedLocationClient.removeLocationUpdates(locationCallback);
}
}
// Cria o Canal de Notificação (obrigatório a partir do Android 8.0)
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"LocationChannel",
"Monitoramento de Localização",
NotificationManager.IMPORTANCE_LOW // Low para não fazer barulho nem vibrar a toda a hora
);
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
}
}

View File

@@ -1,6 +1,9 @@
package com.example.pap_findu;
import android.content.Intent; // <-- ADICIONADO
import android.os.Build; // <-- ADICIONADO
import android.os.Bundle;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
@@ -35,5 +38,18 @@ public class MainActivity extends AppCompatActivity {
NavigationUI.setupWithNavController(binding.navView, navController);
//teste
}
// ========================================================
// CÓDIGO ADICIONADO: INICIAR O RASTREAMENTO EM BACKGROUND
// ========================================================
Intent serviceIntent = new Intent(this, LocationService.class);
// O Android 8.0 (Oreo) ou superior exige o startForegroundService
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent);
} else {
startService(serviceIntent);
}
// ========================================================
}
}

View File

@@ -1,4 +1,4 @@
#Tue Jan 27 16:46:23 WET 2026
#Thu Mar 12 10:10:15 WET 2026
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip