Exercicio SensorExplorer Android Java
Exercicio SensorExplorer Android Java
📱
EXERCÍCIO PRÁTICO
Página 1 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
📌 Pré-requisitos
Antes de começar, certifique-se de ter instalado:
• Android Studio Hedgehog (2023.1.1) ou versão mais recente
• JDK 17 (incluso no Android Studio)
• Dispositivo físico com Android 8.0+ OU emulador com Google Play Services (para
o GPS funcionar melhor)
• Conhecimento básico de Java e layouts XML — tudo será explicado com detalhes!
Página 2 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
1. Na tela inicial, clique em New Project (ou File > New > New Project).
2. Selecione o template Empty Activity e clique em Next.
3. Preencha as informações do projeto:
Campo Valor
Name SensorExplorer
4. Clique em Finish e aguarde o Gradle sincronizar o projeto (pode levar alguns minutos na
primeira vez).
💡 O que é o Gradle?
O Gradle é a ferramenta de build do Android. Ele baixa as bibliotecas necessárias e
compila o projeto. A barra de progresso na parte inferior do Android Studio indica quando
ele está trabalhando.
Página 3 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
Abra o arquivo app/[Link] e, dentro do bloco dependencies { ... }, adicione as linhas abaixo:
// CameraX
implementation("[Link]:camera-core:1.3.1")
implementation("[Link]:camera-camera2:1.3.1")
implementation("[Link]:camera-lifecycle:1.3.1")
implementation("[Link]:camera-view:1.3.1")
// ViewPager2
implementation("androidx.viewpager2:viewpager2:1.0.0")
Ainda no mesmo arquivo, dentro do bloco android { ... }, adicione a linha para ativar o View Binding:
android {
// ... outras configurações ...
buildFeatures {
viewBinding = true
}
}
Após editar, clique em Sync Now na barra amarela que aparece no topo do arquivo, ou vá em File >
Sync Project with Gradle Files.
Página 4 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
2 Configurando as Permissões
<!-- Informa que o app usa câmera (para filtros na Play Store) -->
<uses-feature android:name="[Link]" android:required="false"
/>
<application
android:allowBackup="true"
... >
</application>
</manifest>
Página 5 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
Página 6 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
Nosso app terá uma barra de abas na parte superior, com quatro opções. No Android, isso é
implementado com um TabLayout + ViewPager2. O TabLayout exibe as abas visuais e o ViewPager2
controla qual tela está sendo mostrada.
</LinearLayout>
fragment_camera.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="[Link]
Página 7 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
</LinearLayout>
fragment_gps.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center">
<TextView
android:text="📍 Localização Atual"
android:textSize="22sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp" />
Página 8 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
<TextView
android:id="@+id/tvLatitude"
android:text="Latitude: --"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvLongitude"
android:text="Longitude: --"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
<TextView
android:id="@+id/tvPrecisao"
android:text="Precisão: --"
android:textSize="16sp"
android:textColor="#888888"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
<Button
android:id="@+id/btnObterLocalizacao"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Obter Localização" />
</LinearLayout>
fragment_acelerometro.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center_horizontal">
Página 9 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
</LinearLayout>
fragment_giroscopio.xml
Crie com estrutura idêntica ao fragment_acelerometro.xml, trocando os IDs para tvGiroX, tvGiroY,
tvGiroZ e progressGiroX, progressGiroY, progressGiroZ, e o título para '🌀 Giroscópio'. Os valores são
em rad/s.
💡 Dica de Produtividade
Página 10 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
No Android Studio, você pode usar o modo Design (botão no canto superior direito do
editor XML) para visualizar o layout enquanto edita. Clique em Split para ver o código e o
preview ao mesmo tempo.
Página 11 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
No Android, Fragment é um componente de tela que pode ser inserido dentro de uma Activity. Cada
aba terá seu próprio Fragment, com a lógica de seu sensor.
Para criar um Fragment: clique com o botão direito na pasta do seu pacote
(java/[Link]) > New > Kotlin Class/File > nomeie como CameraFragment.
4.1 — [Link]
A câmera usa a biblioteca CameraX. Em Java, usamos classes anônimas no lugar das lambdas
concisas do Kotlin. Note o uso de new Interface() { ... } para implementar callbacks:
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
binding = [Link](inflater, container, false);
return [Link]();
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
[Link](view, savedInstanceState);
cameraExecutor = [Link]();
iniciarCamera();
[Link](v -> tirarFoto());
}
Página 12 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
[Link](requireContext());
[Link](() -> {
try {
ProcessCameraProvider cameraProvider = [Link]();
CameraSelector cameraSelector =
CameraSelector.DEFAULT_BACK_CAMERA;
[Link]();
[Link](
getViewLifecycleOwner(), cameraSelector,
preview, imageCapture);
} catch (Exception e) {
Log.e("CameraFragment", "Erro ao abrir câmera", e);
}
}, [Link](requireContext()));
}
Página 13 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
@Override
public void onError(@NonNull ImageCaptureException e) {
Log.e("CameraFragment", "Erro ao salvar foto", e);
}
}
);
}
@Override
public void onDestroyView() {
[Link]();
[Link]();
binding = null; // Evita memory leak
}
}
📌 Entendendo o CameraX
Preview — exibe a imagem em tempo real na tela. O usuário vê o que a câmera está
capturando.
ImageCapture — captura um único quadro quando o usuário pressiona o botão.
bindToLifecycle — conecta a câmera ao ciclo de vida do fragment, garantindo que ela seja
liberada automaticamente quando a tela fechar.
Página 14 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
4.2 — [Link]
O GPS usa o FusedLocationProviderClient do Google. Em Java, o LocationCallback é implementado
como classe anônima. O @SuppressLint suprime o aviso de permissão — já verificamos antes:
import [Link].*;
import [Link];
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = [Link](inflater, container, false);
return [Link]();
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
[Link](view, savedInstanceState);
fusedLocationClient = LocationServices
.getFusedLocationProviderClient(requireActivity());
[Link](
v -> iniciarAtualizacoes());
}
Página 15 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
@SuppressLint("MissingPermission")
private void iniciarAtualizacoes() {
LocationRequest request = new [Link](
Priority.PRIORITY_HIGH_ACCURACY, 2000L).build();
[Link](
request, locationCallback, [Link]());
[Link]("Monitorando...");
[Link](false);
}
@Override
public void onDestroyView() {
[Link]();
// IMPORTANTE: Para as atualizacoes ao sair da tela!
[Link](locationCallback);
binding = null;
}
}
⚠️ Consumo de Bateria
Sempre chame removeLocationUpdates() no onDestroyView()! Esquecer esse passo faz o
GPS continuar rodando em segundo plano, drenando a bateria do usuário mesmo com o
app fechado.
Página 16 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
4.3 — [Link]
O acelerômetro usa a API SensorManager nativa do Android. Em Java, implementamos
SensorEventListener na própria classe com implements — obrigando a definir os dois métodos da
interface:
import [Link];
import [Link];
import [Link];
import [Link];
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = [Link](inflater, container,
false);
return [Link]();
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
[Link](view, savedInstanceState);
acelerometro = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (acelerometro == null) {
[Link](requireContext(),
"Acelerometro nao encontrado!", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onResume() {
[Link]();
if (acelerometro != null) {
[Link](
Página 17 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
@Override
public void onPause() {
[Link]();
[Link](this);
}
@Override
public void onSensorChanged(SensorEvent event) {
if ([Link]() == Sensor.TYPE_ACCELEROMETER) {
float x = [Link][0]; // Inclinacao lateral
float y = [Link][1]; // Inclinacao frontal
float z = [Link][2]; // Vertical (gravidade ~9.8)
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
@Override
public void onDestroyView() {
[Link]();
binding = null;
}
}
Página 18 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
Página 19 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
4.4 — [Link]
O giroscópio mede velocidade angular em rad/s. A estrutura é idêntica ao AcelerometroFragment —
apenas o tipo de sensor e os IDs de binding mudam:
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = [Link](inflater, container, false);
return [Link]();
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
[Link](view, savedInstanceState);
sensorManager = (SensorManager) requireActivity()
.getSystemService(Context.SENSOR_SERVICE);
// Unica diferenca: TYPE_GYROSCOPE em vez de TYPE_ACCELEROMETER
giroscopio = [Link](Sensor.TYPE_GYROSCOPE);
}
@Override
public void onResume() {
[Link]();
if (giroscopio != null) {
[Link](
this, giroscopio, SensorManager.SENSOR_DELAY_UI);
}
}
@Override
public void onPause() {
[Link]();
[Link](this);
}
@Override
public void onSensorChanged(SensorEvent event) {
if ([Link]() == Sensor.TYPE_GYROSCOPE) {
float x = [Link][0]; // Rotacao em torno de X (pitch)
float y = [Link][1]; // Rotacao em torno de Y (yaw)
float z = [Link][2]; // Rotacao em torno de Z (roll)
Página 20 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
[Link](
[Link]("Giro X: %.3f rad/s", x));
[Link](
[Link]("Giro Y: %.3f rad/s", y));
[Link](
[Link]("Giro Z: %.3f rad/s", z));
[Link](
[Link](0, [Link](200, (int)(100 + x * 20))));
[Link](
[Link](0, [Link](200, (int)(100 + y * 20))));
[Link](
[Link](0, [Link](200, (int)(100 + z * 20))));
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
@Override
public void onDestroyView() {
[Link]();
binding = null;
}
}
Página 21 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
import [Link];
import [Link];
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
binding = [Link](getLayoutInflater());
setContentView([Link]());
configurarAbas();
solicitarPermissoes();
}
@NonNull @Override
public Fragment createFragment(int position) {
switch (position) {
case 0: return new CameraFragment();
case 1: return new GpsFragment();
Página 22 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
[Link](adapter);
💡 switch vs when
Em Java usamos switch/case para seleções múltiplas. No Kotlin, o equivalente é o when,
com sintaxe mais concisa. Ambos verificam o valor de uma variável e executam o bloco
correspondente.
Página 23 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
Página 24 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
7 Desafios e Melhorias
O app básico está funcional! Agora, tente implementar esses desafios para aprofundar o aprendizado:
// No [Link]:
implementation("[Link]:osmdroid-android:6.1.17")
Página 25 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
// No onSensorChanged do AcelerometroFragment:
double magnitude = [Link](x * x + y * y + z * z);
Página 26 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes
Veja as principais diferenças de sintaxe entre Java e Kotlin que você encontrou neste exercício:
Seleção múltipla switch (x) { case 1: ... } when (x) { 1 -> ... }
Bom trabalho! Agora você tem um app Java com câmera, GPS, acelerômetro e giroscópio
funcionando. 🎉
Página 27 de 27