0% acharam este documento útil (0 voto)
4 visualizações27 páginas

Exercicio SensorExplorer Android Java

O documento é um guia prático para iniciantes no desenvolvimento de um aplicativo Android chamado App Sensor Explorer, que utiliza sensores como câmera, GPS, acelerômetro e giroscópio. O guia detalha a criação do projeto no Android Studio, configuração de permissões e implementação de layouts com abas para cada sensor. Inclui instruções passo a passo para adicionar dependências, criar layouts e gerenciar permissões em tempo de execução.

Enviado por

rovilson.freitas
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
4 visualizações27 páginas

Exercicio SensorExplorer Android Java

O documento é um guia prático para iniciantes no desenvolvimento de um aplicativo Android chamado App Sensor Explorer, que utiliza sensores como câmera, GPS, acelerômetro e giroscópio. O guia detalha a criação do projeto no Android Studio, configuração de permissões e implementação de layouts com abas para cada sensor. Inclui instruções passo a passo para adicionar dependências, criar layouts e gerenciar permissões em tempo de execução.

Enviado por

rovilson.freitas
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd

App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

📱
EXERCÍCIO PRÁTICO

App Sensor Explorer


Câmera • GPS • Acelerômetro • Giroscópio

Desenvolvimento Android com Android Studio


Guia completo para turmas iniciantes — Java

🎯 Nível: Iniciante Duração: 3-4 horas Java + Android Studio

Página 1 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

Visão Geral do Projeto


Neste exercício você vai criar o App Sensor Explorer — um aplicativo Android que usa os principais
recursos de hardware do celular em uma única interface. Ao final, você terá um app funcional com
quatro abas, cada uma demonstrando um sensor diferente do dispositivo.

O que você vai construir:

Aba Recurso O que demonstra


1 📷 Câmera Tirar foto e exibir na tela usando CameraX
2 📍 GPS Obter coordenadas de latitude e longitude em tempo real
3 📐 Acelerômetro Medir aceleração nos eixos X, Y e Z com barra visual
4 🌀 Giroscópio Medir rotação do dispositivo nos três eixos

📌 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 Criando o Projeto no Android Studio

1.1 — Novo Projeto


Abra o Android Studio e siga os passos abaixo para criar seu projeto:

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

Package name [Link]

Save location (escolha uma pasta de sua preferência)

Language Java ← IMPORTANTE: selecionar Java aqui!

Minimum SDK API 24 (Android 7.0) — cobre 98% dos dispositivos

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.

1.2 — Estrutura de Arquivos que Usaremos


Após criar o projeto, você verá na aba Project (esquerda) uma estrutura de pastas. Vamos trabalhar
principalmente com estes arquivos:

• app/manifests/[Link] — permissões do aplicativo


• app/src/main/java/.../[Link] — lógica principal
• app/src/main/res/layout/activity_main.xml — layout da tela principal
• app/[Link] — dependências/bibliotecas

Página 3 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

1.3 — Adicionando as Dependências


Precisamos adicionar três bibliotecas ao projeto: CameraX (para a câmera), Play Services Location
(para o GPS) e View Binding (para facilitar o acesso aos elementos visuais).

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")

// GPS (Google Play Services)


implementation("[Link]:play-services-location:21.1.0")

// Material Design (para TabLayout)


implementation("[Link]:material:1.11.0")

// 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.

⚠️ Atenção — Java vs Kotlin no Gradle


O arquivo [Link] usa sintaxe Kotlin para configuração, mas isso é diferente do
código Java do seu app. Você ainda escreverá todo o código do app em Java — o .kts é
apenas para configurações do projeto.

Página 4 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

2 Configurando as Permissões

Os recursos de hardware do celular (câmera, GPS, sensores) precisam da autorização explícita do


usuário. No Android, isso funciona em dois níveis:

• Permissões declaradas no [Link] — informa ao sistema operacional que o app


pode usar aquele recurso
• Permissões solicitadas em tempo de execução — o app pede ao usuário, que pode aceitar ou
recusar, diretamente em uma caixa de diálogo

2.1 — Editando o [Link]


Abra o arquivo app/manifests/[Link] e adicione as permissões antes da tag
<application>:

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="[Link]

<!-- Permissão para usar a câmera -->


<uses-permission android:name="[Link]" />

<!-- Permissões de localização (GPS) -->


<uses-permission android:name="[Link].ACCESS_FINE_LOCATION" />
<uses-permission android:name="[Link].ACCESS_COARSE_LOCATION" />

<!-- 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>

📌 Por que duas permissões de localização?


ACCESS_FINE_LOCATION usa o GPS real do dispositivo, com precisão de metros.
ACCESS_COARSE_LOCATION usa Wi-Fi e torres de celular, com precisão de centenas
de metros.
Declarar ambas permite que o sistema escolha a melhor opção disponível.

Página 5 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

2.2 — Solicitando Permissões em Tempo de Execução (Java)


A partir do Android 6.0, permissões sensíveis precisam ser solicitadas enquanto o app está em uso.
Em Java, fazemos isso com ActivityResultLauncher dentro da MainActivity:

// Dentro da classe MainActivity (declarado como campo)

private final ActivityResultLauncher<String[]> permissionsLauncher =


registerForActivityResult(
new [Link](),
permissions -> {
boolean todasConcedidas = true;
for (Boolean concedida : [Link]()) {
if (!concedida) { todasConcedidas = false; break; }
}
if (todasConcedidas) {
inicializarRecursos();
} else {
[Link](this,
"Permissões necessárias não foram concedidas.",
Toast.LENGTH_LONG).show();
}
}
);

private void solicitarPermissoes() {


[Link](new String[]{
[Link],
[Link].ACCESS_FINE_LOCATION,
[Link].ACCESS_COARSE_LOCATION
});
}

💡 Java vs Kotlin — Diferenças Importantes


Em Java, cada instrução termina com ponto e vírgula (;). Esquecer o ; é o erro mais
comum!
Lambdas em Java (permissions -> { ... }) funcionam como funções anônimas para
interfaces funcionais.
Em Java, todos os tipos de variáveis devem ser declarados explicitamente (boolean, int,
String, etc.).

Página 6 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

3 Criando o Layout com Abas (TabLayout)

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.

3.1 — Layout Principal (activity_main.xml)


Abra o arquivo res/layout/activity_main.xml. Troque todo o conteúdo pelo código abaixo:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout
xmlns:android="[Link]
xmlns:app="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!-- Barra de abas na parte superior -->


<[Link]
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill" />

<!-- Área de conteúdo — muda conforme a aba selecionada -->


<[Link].ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>

3.2 — Criando os Layouts de Cada Aba


Crie quatro arquivos de layout em res/layout/. Clique com o botão direito na pasta layout > New >
Layout Resource File.

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">

<!-- Preview da câmera -->


<[Link]
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />

<!-- Foto tirada -->


<ImageView
android:id="@+id/imageViewFoto"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:visibility="gone" />

<!-- Botão de tirar foto -->


<Button
android:id="@+id/btnTirarFoto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="📷 Tirar Foto" />

</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">

<TextView android:text="📐 Acelerômetro"


android:textSize="22sp" android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp" />

Página 9 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

<!-- Eixo X -->


<TextView android:id="@+id/tvEixoX"
android:text="Eixo X: 0.00 m/s²"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar android:id="@+id/progressX"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="200" android:progress="100"
android:layout_marginBottom="16dp" />

<!-- Eixo Y -->


<TextView android:id="@+id/tvEixoY"
android:text="Eixo Y: 0.00 m/s²"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar android:id="@+id/progressY"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="200" android:progress="100"
android:layout_marginBottom="16dp" />

<!-- Eixo Z -->


<TextView android:id="@+id/tvEixoZ"
android:text="Eixo Z: 0.00 m/s²"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar android:id="@+id/progressZ"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="200" android:progress="100" />

</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

4 Criando os Fragments (Telas de Cada Aba)

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];

public class CameraFragment extends Fragment {

private FragmentCameraBinding binding;


private ExecutorService cameraExecutor;
private ImageCapture imageCapture;

@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());
}

private void iniciarCamera() {


ListenableFuture<ProcessCameraProvider> future =

Página 12 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

[Link](requireContext());

[Link](() -> {
try {
ProcessCameraProvider cameraProvider = [Link]();

Preview preview = new [Link]().build();


[Link](
[Link]());

imageCapture = new [Link]()


.setCaptureMode(
ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build();

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()));
}

private void tirarFoto() {


if (imageCapture == null) return;

File arquivo = new File(requireContext().getCacheDir(),


"foto_temp.jpg");
[Link] opts =
new [Link](arquivo).build();

// Classe anônima para o callback de resultado


[Link](opts, cameraExecutor,
new [Link]() {
@Override
public void onImageSaved(
@NonNull [Link] out) {
requireActivity().runOnUiThread(() -> {
[Link]([Link]);
[Link](
[Link](arquivo));
});
}

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];

public class GpsFragment extends Fragment {

private FragmentGpsBinding binding;


private FusedLocationProviderClient fusedLocationClient;
private LocationCallback locationCallback;

@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());

// Classe anônima — implementa dois métodos de LocationCallback


locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult result) {
Location local = [Link]();
if (local != null) {
[Link](
[Link]("Latitude: %.6f", [Link]()));
[Link](
[Link]("Longitude: %.6f", [Link]()));
[Link](
[Link]("Precisao: +/-%.0f metros",
[Link]()));
}
}
};

[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];

// implements SensorEventListener exige onSensorChanged e onAccuracyChanged


public class AcelerometroFragment extends Fragment
implements SensorEventListener {

private FragmentAcelerometroBinding binding;


private SensorManager sensorManager;
private Sensor acelerometro;

@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);

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

this, acelerometro, SensorManager.SENSOR_DELAY_UI);


}
}

@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)

[Link]([Link]("Eixo X: %.2f m/s2", x));


[Link]([Link]("Eixo Y: %.2f m/s2", y));
[Link]([Link]("Eixo Z: %.2f m/s2", z));

// [Link]/min substitui o coerceIn() do Kotlin


[Link](
[Link](0, [Link](200, (int)(100 + x * 5))));
[Link](
[Link](0, [Link](200, (int)(100 + y * 5))));
[Link](
[Link](0, [Link](200, (int)(100 + z * 5))));
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }

@Override
public void onDestroyView() {
[Link]();
binding = null;
}
}

📌 Entendendo os Eixos do Acelerômetro


Eixo X (lateral): positivo quando o telefone inclina para a direita.
Eixo Y (frontal): positivo quando o topo do telefone inclina para cima.
Eixo Z (vertical): em repouso, Z ≈ 9.8 m/s² (aceleração da gravidade).
Em Java, [Link](0, [Link](200, valor)) equivale ao coerceIn(0, 200) do Kotlin —
limita o valor ao intervalo da barra de progresso.

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:

public class GiroscopioFragment extends Fragment


implements SensorEventListener {

private FragmentGiroscopioBinding binding;


private SensorManager sensorManager;
private Sensor giroscopio;

@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

5 Conectando Tudo na [Link]

A MainActivity cria as abas, registra os fragments e gerencia permissões. Em Java, o


FragmentStateAdapter é implementado como uma classe anônima com switch/case:

import [Link];
import [Link];

public class MainActivity extends AppCompatActivity {

private ActivityMainBinding binding;

// Launcher declarado como campo — necessário em Java


private final ActivityResultLauncher<String[]> permissionsLauncher =
registerForActivityResult(
new [Link](),
permissions -> {
boolean todas = true;
for (Boolean ok : [Link]()) {
if (!ok) { todas = false; break; }
}
if (todas) inicializarRecursos();
else [Link](this, "Permissoes negadas.",
Toast.LENGTH_LONG).show();
}
);

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
binding = [Link](getLayoutInflater());
setContentView([Link]());
configurarAbas();
solicitarPermissoes();
}

private void configurarAbas() {


// Classe anônima para o adapter de fragments
FragmentStateAdapter adapter = new FragmentStateAdapter(this) {
@Override
public int getItemCount() { return 4; }

@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

case 2: return new AcelerometroFragment();


case 3: return new GiroscopioFragment();
default: throw new IllegalArgumentException(
"Posicao invalida: " + position);
}
}
};

[Link](adapter);

// Conecta TabLayout ao ViewPager2


new TabLayoutMediator(
[Link], [Link],
(tab, position) -> {
switch (position) {
case 0: [Link]("Camera"); break;
case 1: [Link]("GPS"); break;
case 2: [Link]("Acel."); break;
case 3: [Link]("Giro"); break;
}
}
).attach();
}

private void inicializarRecursos() {


[Link](this, "Permissoes concedidas!",
Toast.LENGTH_SHORT).show();
}

private void solicitarPermissoes() {


[Link](new String[]{
[Link],
[Link].ACCESS_FINE_LOCATION,
[Link].ACCESS_COARSE_LOCATION
});
}
}

💡 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

6 Executando e Testando o App

6.1 — Executando no Emulador


5. No Android Studio, clique no botão ▶ Run (ou pressione Shift + F10).
6. Aguarde o build completar e o app abrir no emulador.
7. O app pedirá permissões — clique em Permitir em todas.
8. Navegue pelas quatro abas e explore os sensores.

📌 Testando sensores no Emulador


GPS: no emulador, vá em (...) Extended Controls > Location e envie uma coordenada
fictícia.
Acelerômetro/Giroscópio: em Extended Controls > Virtual Sensors, arraste para simular
movimentos.
Câmera: o emulador usa uma câmera virtual com uma cena 3D. Para resultados reais, use
um dispositivo físico.

6.2 — Executando em Dispositivo Físico


9. Ative o Modo Desenvolvedor no celular: vá em Configurações > Sobre o telefone > toque em
Número da Versão 7 vezes.
10. Em Configurações > Opções do desenvolvedor, ative Depuração USB.
11. Conecte o celular ao computador via USB. Aceite a confirmação de depuração no celular.
12. No Android Studio, selecione seu dispositivo no menu de dispositivos (parte superior) e clique
em ▶ Run.

⚠️ Problema: app travando ao pedir permissão?


Certifique-se de que as permissões estão declaradas no [Link] E que você
está chamando requestPermissions() em tempo de execução. Ter só uma das duas partes
causa crash.

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:

Desafio 1 — Salvar a Foto na Galeria ⭐


Em vez de salvar a foto na pasta de cache temporário, use o MediaStore para salvar na galeria de
fotos do dispositivo. Isso requer a permissão WRITE_EXTERNAL_STORAGE em versões antigas do
Android.

// Dentro de tirarFoto(), use ContentValues para salvar na galeria:


ContentValues cv = new ContentValues();
[Link]([Link].DISPLAY_NAME,
"foto_" + [Link]() + ".jpg");
[Link]([Link].MIME_TYPE, "image/jpeg");

Uri uri = requireContext().getContentResolver().insert(


[Link].EXTERNAL_CONTENT_URI, cv);

// Use uri como destino no [Link](uri, ...)

Desafio 2 — Exibir Localização no Mapa ⭐⭐


Use a biblioteca OSMDroid (OpenStreetMap) para mostrar um mapa com um marcador na posição
atual do usuário. É uma alternativa gratuita ao Google Maps.

// No [Link]:
implementation("[Link]:osmdroid-android:6.1.17")

// No Fragment (após obter latitude e longitude):


IMapController mapController = [Link]();
[Link](15.0);
GeoPoint point = new GeoPoint(latitude, longitude);
[Link](point);

Marker marker = new Marker([Link]);


[Link](point);
[Link]("Voce esta aqui");
[Link]().add(marker);

Página 25 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

Desafio 3 — Detectar Gestos pelo Acelerômetro ⭐⭐⭐


Implemente a detecção de shake (agitar o celular). Se a magnitude da aceleração total ultrapassar um
limiar, toque um som ou vibre o dispositivo.

// No onSensorChanged do AcelerometroFragment:
double magnitude = [Link](x * x + y * y + z * z);

if (magnitude > 15.0) { // Limiar de shake


Vibrator vibrator = (Vibrator) requireActivity()
.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && [Link]()) {
[Link]([Link](
200, VibrationEffect.DEFAULT_AMPLITUDE));
}
}

Página 26 de 27
App Sensor Explorer — Exercício Android Studio (Java) Guia para Iniciantes

8 Java vs Kotlin — Comparativo Rápido

Veja as principais diferenças de sintaxe entre Java e Kotlin que você encontrou neste exercício:

Recurso Java (este exercício) Kotlin equivalente


Variável String nome = "Joao"; val nome = "João"

Nulo seguro if (obj != null) { ... } obj?.let { ... }

Lambda v -> doSomething(v) { v -> doSomething(v) }

Seleção múltipla switch (x) { case 1: ... } when (x) { 1 -> ... }

Interface impl. implements SensorEventListener : SensorEventListener

Classe anônima new Interface() { ... } object : Interface { ... }

Fim de instrução Ponto e vírgula obrigatório ; Opcional (raramente usado)

Tipo de variável Sempre declarado (int, float) Inferido pelo compilador


(val/var)

💡 Recursos de Estudo Recomendados

• [Link] — Documentação oficial do Android (em inglês)


• [Link]/codelabs — Tutoriais interativos gratuitos da Google
• [Link] — Para resolver erros e dúvidas específicas

Bom trabalho! Agora você tem um app Java com câmera, GPS, acelerômetro e giroscópio
funcionando. 🎉

Página 27 de 27

Você também pode gostar