a localizaçao esta funcionando + ou - certo
This commit is contained in:
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@@ -18,12 +18,12 @@
|
||||
<targets>
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=rogmvsfmmfus95e6" />
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Pixel_9_Pro.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Pixel_9_Pro.avd" />
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Pixel_9_Pro_filho.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</targets>
|
||||
|
||||
@@ -4,16 +4,23 @@
|
||||
|
||||
<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.POST_NOTIFICATIONS" />
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<queries>
|
||||
<package android:name="com.google.android.gms" />
|
||||
<intent>
|
||||
<action android:name="com.google.android.geo.API_KEY" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
@@ -22,12 +29,17 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.PAP_FindU">
|
||||
android:theme="@style/Theme.PAP_FindU"
|
||||
tools:targetApi="34">
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
android:value="AIzaSyAxen212OKqkfpu1AbWajLGTCTSdRhJWlM" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
|
||||
<service
|
||||
android:name=".LocationService"
|
||||
android:enabled="true"
|
||||
@@ -37,9 +49,11 @@
|
||||
<activity
|
||||
android:name=".CriarConta"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".Recuperar_Passe"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ChatActivity"
|
||||
android:exported="false" />
|
||||
@@ -56,6 +70,7 @@
|
||||
<activity
|
||||
android:name=".AddZoneActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
@@ -64,6 +79,7 @@
|
||||
<activity
|
||||
android:name=".EditProfileActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".SecurityActivity"
|
||||
android:exported="false" />
|
||||
|
||||
@@ -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<String, Object> 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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user