From 86221e5179408a8712b7a956fa26d7d1c884c728 Mon Sep 17 00:00:00 2001 From: 230408 <230408@epvc.pt> Date: Thu, 12 Mar 2026 17:16:29 +0000 Subject: [PATCH] =?UTF-8?q?a=20localiza=C3=A7ao=20esta=20funcionando=20+?= =?UTF-8?q?=20ou=20-=20certo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetSelector.xml | 4 +- app/src/main/AndroidManifest.xml | 24 ++++++++-- .../example/pap_findu/LocationService.java | 41 +++++++++------- .../com/example/pap_findu/login_activity.java | 9 ++++ .../example/pap_findu/ui/map/MapFragment.java | 47 +++++-------------- 5 files changed, 68 insertions(+), 57 deletions(-) diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 3b4d6bd..ac5ee25 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -18,12 +18,12 @@ - + - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9a9057d..dd316b9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,16 +4,23 @@ - + - - + + + + + + + + + + android:theme="@style/Theme.PAP_FindU" + tools:targetApi="34"> + + + + @@ -56,6 +70,7 @@ + + diff --git a/app/src/main/java/com/example/pap_findu/LocationService.java b/app/src/main/java/com/example/pap_findu/LocationService.java index fb295b9..730a43a 100644 --- a/app/src/main/java/com/example/pap_findu/LocationService.java +++ b/app/src/main/java/com/example/pap_findu/LocationService.java @@ -14,6 +14,7 @@ import android.location.Location; import android.os.Build; import android.os.IBinder; import android.os.Looper; +import android.util.Log; // Importação adicionada import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -26,9 +27,7 @@ import com.google.android.gms.location.LocationResult; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.Priority; -// IMPORTAÇÕES ADICIONADAS PARA A AUTENTICAÇÃO AUTOMÁTICA -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.auth.FirebaseUser; +// Importações do Firebase import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; @@ -55,15 +54,14 @@ public class LocationService extends Service { fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // ================================================================= - // AUTOMAÇÃO: Vai buscar o ID do Filho que está logado neste telemóvel + // AUTOMAÇÃO: Vai buscar o código de 6 dígitos salvo no Login // ================================================================= - FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); + String childCode = getSharedPreferences("FindU_Prefs", MODE_PRIVATE) + .getString("child_access_code", null); - if (currentUser != null) { - String myUid = currentUser.getUid(); // Pega o ID único gerado pelo Firebase - - // Cria a referência da base de dados usando este ID dinâmico - databaseReference = FirebaseDatabase.getInstance().getReference("users/" + myUid + "/live_location"); + if (childCode != null) { + // Cria a pasta usando o código de 6 dígitos (ex: users/484981/live_location) + databaseReference = FirebaseDatabase.getInstance().getReference("users/" + childCode + "/live_location"); } } @@ -97,7 +95,7 @@ public class LocationService extends Service { } } catch (Exception e) { - // Se o sistema operativo forçar uma paragem (muito comum em emuladores), apanhamos o erro aqui! + Log.e("LocationService", "Erro ao iniciar Foreground Service: " + e.getMessage()); e.printStackTrace(); stopSelf(); } @@ -123,7 +121,7 @@ public class LocationService extends Service { locationData.put("longitude", location.getLongitude()); locationData.put("last_updated", System.currentTimeMillis()); - // Verifica se o utilizador não é nulo antes de enviar para o Firebase + // Verifica se a referência não é nula antes de enviar para o Firebase if (databaseReference != null) { databaseReference.setValue(locationData); } @@ -131,11 +129,22 @@ public class LocationService extends Service { } }; - // Outro try-catch de segurança para a comunicação com os serviços do Google (GMS) + // MELHORIA AQUI: Try-catch mais abrangente para lidar com o erro de "Broker" try { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); - } catch (SecurityException e) { - e.printStackTrace(); + } catch (Exception e) { + Log.e("LocationService", "Erro crítico nos Google Play Services (Broker): " + e.getMessage()); + + // Plano B: Tenta obter pelo menos a última localização conhecida + fusedLocationClient.getLastLocation().addOnSuccessListener(location -> { + if (location != null && databaseReference != null) { + Map locationData = new HashMap<>(); + locationData.put("latitude", location.getLatitude()); + locationData.put("longitude", location.getLongitude()); + locationData.put("last_updated", System.currentTimeMillis()); + databaseReference.setValue(locationData); + } + }); } } @@ -154,7 +163,7 @@ public class LocationService extends Service { NotificationChannel channel = new NotificationChannel( "LocationChannel", "Monitoramento de Localização", - NotificationManager.IMPORTANCE_LOW // Low para não fazer barulho nem vibrar + NotificationManager.IMPORTANCE_LOW ); NotificationManager manager = getSystemService(NotificationManager.class); if (manager != null) { diff --git a/app/src/main/java/com/example/pap_findu/login_activity.java b/app/src/main/java/com/example/pap_findu/login_activity.java index 114cfaf..b2679af 100644 --- a/app/src/main/java/com/example/pap_findu/login_activity.java +++ b/app/src/main/java/com/example/pap_findu/login_activity.java @@ -1,6 +1,7 @@ package com.example.pap_findu; import android.content.Intent; +import android.content.SharedPreferences; // <-- Importação adicionada automaticamente import android.os.Bundle; import android.text.InputType; import android.text.TextUtils; @@ -196,6 +197,14 @@ public class login_activity extends AppCompatActivity { // 1. Invalida o código para ninguém usar de novo db.collection("login_codes").document(code).update("used", true); + // ======================================================= + // 2. NOVA LINHA: GUARDA O CÓDIGO NA MEMÓRIA DO TELEMÓVEL! + // ======================================================= + getSharedPreferences("FindU_Prefs", MODE_PRIVATE) + .edit() + .putString("child_access_code", code) + .apply(); + Toast.makeText(this, "Conectado como Filho!", Toast.LENGTH_SHORT).show(); goToMainActivity(); } else { diff --git a/app/src/main/java/com/example/pap_findu/ui/map/MapFragment.java b/app/src/main/java/com/example/pap_findu/ui/map/MapFragment.java index 22a387f..db44db4 100644 --- a/app/src/main/java/com/example/pap_findu/ui/map/MapFragment.java +++ b/app/src/main/java/com/example/pap_findu/ui/map/MapFragment.java @@ -31,7 +31,7 @@ import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.ValueEventListener; import com.google.firebase.firestore.FirebaseFirestore; -import com.google.firebase.firestore.QuerySnapshot; +import com.google.firebase.firestore.QueryDocumentSnapshot; public class MapFragment extends Fragment implements OnMapReadyCallback { @@ -41,13 +41,11 @@ public class MapFragment extends Fragment implements OnMapReadyCallback { private FirebaseFirestore db; private FirebaseAuth auth; - // Variáveis para o Mapa e Tempo Real private GoogleMap mMap; private Marker childMarker; private DatabaseReference locationRef; private ValueEventListener locationListener; - // VARIÁVEL ADICIONADA PARA GUARDAR O ID DA CRIANÇA AUTOMATICAMENTE private String currentChildId = null; public View onCreateView(@NonNull LayoutInflater inflater, @@ -83,7 +81,7 @@ public class MapFragment extends Fragment implements OnMapReadyCallback { if (user == null) return; if (user.isAnonymous()) { - if (btnAddChild != null) btnAddChild.setVisibility(View.GONE); + // Se o utilizador é anónimo (Filho), ele vê o próprio mapa showMapState(); return; } @@ -102,18 +100,15 @@ public class MapFragment extends Fragment implements OnMapReadyCallback { .addOnCompleteListener(task -> { if (task.isSuccessful() && task.getResult() != null && !task.getResult().isEmpty()) { - // ================================================================= - // AUTOMAÇÃO: Encontra a criança e extrai o ID dela! - // ================================================================= + // Pegamos no código de acesso do primeiro filho encontrado var document = task.getResult().getDocuments().get(0); - // MUITO IMPORTANTE: Mude "uid" para o nome do campo na sua base de dados que tem o ID do filho! - currentChildId = document.getString("uid"); + // USAMOS O accessCode COMO CHAVE DE LIGAÇÃO + currentChildId = document.getString("accessCode"); if (currentChildId != null) { - showMapState(); // Se encontrou o ID, carrega o mapa + showMapState(); } else { - Toast.makeText(getContext(), "Erro: Criança encontrada, mas sem ID.", Toast.LENGTH_SHORT).show(); showEmptyState(); } } else { @@ -140,21 +135,15 @@ public class MapFragment extends Fragment implements OnMapReadyCallback { @Override public void onMapReady(@NonNull GoogleMap googleMap) { mMap = googleMap; - mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(0, 0), 2f)); - // Inicia a escuta APENAS se tivermos encontrado um ID válido if (currentChildId != null) { startListeningToChildLocation(); - } else { - Toast.makeText(getContext(), "A aguardar ligação à criança...", Toast.LENGTH_SHORT).show(); } } private void startListeningToChildLocation() { - // ================================================================= - // AUTOMAÇÃO: Usa a variável currentChildId em vez de texto fixo - // ================================================================= + // Escuta na pasta baseada no Código de Acesso locationRef = FirebaseDatabase.getInstance().getReference("users/" + currentChildId + "/live_location"); locationListener = new ValueEventListener() { @@ -168,25 +157,18 @@ public class MapFragment extends Fragment implements OnMapReadyCallback { LatLng childPosition = new LatLng(lat, lng); if (childMarker == null) { - MarkerOptions markerOptions = new MarkerOptions() - .position(childPosition) - .title("Criança"); - - childMarker = mMap.addMarker(markerOptions); - mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(childPosition, 16f)); + childMarker = mMap.addMarker(new MarkerOptions().position(childPosition).title("Filho")); + mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(childPosition, 15f)); } else { childMarker.setPosition(childPosition); - mMap.animateCamera(CameraUpdateFactory.newLatLng(childPosition)); } } - } else { - Log.w("MapFragment", "Pasta de localização vazia ou inexistente para o ID: " + currentChildId); } } @Override public void onCancelled(@NonNull DatabaseError error) { - Log.e("MapFragment", "Erro ao ler localização: " + error.getMessage()); + Log.e("MapFragment", "Erro: " + error.getMessage()); } }; @@ -214,18 +196,13 @@ public class MapFragment extends Fragment implements OnMapReadyCallback { private void showCodeDialog(String code) { if (getContext() == null) return; - ClipboardManager clipboard = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("Código", code); - clipboard.setPrimaryClip(clip); - Toast.makeText(getContext(), "Código copiado!", Toast.LENGTH_SHORT).show(); + clipboard.setPrimaryClip(ClipData.newPlainText("Código", code)); new AlertDialog.Builder(getContext()) .setTitle("Filho Adicionado!") - .setMessage("O código de acesso é: " + code + "\n\n(Já copiado automaticamente)") - .setCancelable(false) + .setMessage("O código de acesso é: " + code) .setPositiveButton("Ir para o Mapa", (dialog, which) -> checkIfHasChildren()) - .setNegativeButton("Adicionar Outro", (dialog, which) -> dialog.dismiss()) .show(); } } \ No newline at end of file