Hola amigos 👋 Bienvenidos a un nuevo tutorial de Universo Android. Hoy aprenderemos a programar para Wear OS, el sistema operativo de Google para smartwatches y dispositivos wearables, creando aplicaciones optimizadas para pantallas pequeñas y circulares.
Al finalizar este tutorial tendrás una aplicación que incluirá:
- Configuración completa de proyecto Wear OS
- Diseños adaptados a pantallas circulares
- Notificaciones en smartwatch
- Complicaciones para watch faces
- Sensores y monitoreo de actividad fÃsica
- Sincronización con dispositivo móvil
- Interfaz optimizada para wearables
🟩 1. ¿Qué es Wear OS?
Wear OS es el sistema operativo de Google diseñado especÃficamente para smartwatches y dispositivos wearables. Permite crear aplicaciones que aprovechan las caracterÃsticas únicas de estos dispositivos: pantallas pequeñas, interacción rápida, sensores de salud y notificaciones instantáneas.
🟩 2. Requisitos Previos
Antes de comenzar necesitas:
- Android Studio (versión actualizada)
- SDK de Android API 30 o superior
- Smartwatch con Wear OS o emulador configurado
- Conocimientos básicos de Android
🟩 3. Crear el Proyecto Wear OS en Android Studio
Paso 1: Nuevo Proyecto
- Abre Android Studio
- Selecciona New Project
- En la pestaña Wear OS, selecciona Empty Wear App
- Configura el nombre y paquete
- Selecciona API 30: Android 11.0 (Wear OS 3) como mÃnimo
- Finaliza la creación
🟩 4. Configurar build.gradle
Abre el archivo build.gradle (Module: app) y verifica las dependencias:
plugins {
id 'com.android.application'
}
android {
namespace 'com.example.wearosapp'
compileSdk 34
defaultConfig {
applicationId "com.example.wearosapp"
minSdk 30
targetSdk 34
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// Wear OS dependencies
implementation 'androidx.wear:wear:1.3.0'
implementation 'com.google.android.support:wearable:2.9.0'
compileOnly 'com.google.android.wearable:wearable:2.9.0'
// Material Design para Wear OS
implementation 'androidx.wear:wear-input:1.1.0'
implementation 'androidx.wear:wear-ongoing:1.0.0'
// Core dependencies
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
// Play Services para sensores
implementation 'com.google.android.gms:play-services-wearable:18.1.0'
}Sincroniza el proyecto después de agregar las dependencias.
🟩 5. Diseño XML para Wear OS
Crea un archivo llamado:
📄 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:padding="16dp"
app:boxedEdges="all">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- TÃtulo de la App -->
<TextView
android:id="@+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wear OS App"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="20dp" />
<!-- Contador de Pasos -->
<TextView
android:id="@+id/txtStepCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#4CAF50"
android:textSize="48sp"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@id/txtTitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/txtStepLabel"
android:layout_marginTop="20dp" />
<!-- Etiqueta de Pasos -->
<TextView
android:id="@+id/txtStepLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pasos hoy"
android:textColor="#AAAAAA"
android:textSize="16sp"
app:layout_constraintTop_toBottomOf="@id/txtStepCount"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/btnStart" />
<!-- Botón Iniciar -->
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Iniciar"
android:textColor="#FFFFFF"
android:backgroundTint="#2196F3"
app:layout_constraintTop_toBottomOf="@id/txtStepLabel"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/btnNotification"
android:layout_marginTop="20dp" />
<!-- Botón Notificación -->
<Button
android:id="@+id/btnNotification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Notificación"
android:textColor="#FFFFFF"
android:backgroundTint="#FF5722"
app:layout_constraintTop_toBottomOf="@id/btnStart"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="12dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.wear.widget.BoxInsetLayout>🟩 6. Diseño XML con Lista Circular (WearableRecyclerView)
Crea un archivo llamado:
📄 activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
app:boxedEdges="all">
<androidx.wear.widget.WearableRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layoutManager="androidx.wear.widget.WearableLinearLayoutManager" />
</androidx.wear.widget.BoxInsetLayout>🟩 7. Lógica Java Principal
📄 MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private static final String CHANNEL_ID = "wear_channel";
private static final int NOTIFICATION_ID = 1;
TextView txtStepCount, txtTitle;
Button btnStart, btnNotification;
SensorManager sensorManager;
Sensor stepCounterSensor;
int stepCount = 0;
boolean isTracking = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Inicializar vistas
txtTitle = findViewById(R.id.txtTitle);
txtStepCount = findViewById(R.id.txtStepCount);
btnStart = findViewById(R.id.btnStart);
btnNotification = findViewById(R.id.btnNotification);
// Configurar sensor de pasos
setupStepCounter();
// Crear canal de notificación
createNotificationChannel();
// Configurar botones
btnStart.setOnClickListener(v -> toggleTracking());
btnNotification.setOnClickListener(v -> sendNotification());
}
private void setupStepCounter() {
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager != null) {
stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
if (stepCounterSensor == null) {
Toast.makeText(this, "Sensor de pasos no disponible", Toast.LENGTH_SHORT).show();
}
}
}
private void toggleTracking() {
if (!isTracking) {
startTracking();
} else {
stopTracking();
}
}
private void startTracking() {
if (stepCounterSensor != null) {
sensorManager.registerListener(this, stepCounterSensor, SensorManager.SENSOR_DELAY_NORMAL);
isTracking = true;
btnStart.setText("Detener");
btnStart.setBackgroundTintList(getColorStateList(android.R.color.holo_red_dark));
Toast.makeText(this, "Seguimiento iniciado", Toast.LENGTH_SHORT).show();
}
}
private void stopTracking() {
sensorManager.unregisterListener(this);
isTracking = false;
btnStart.setText("Iniciar");
btnStart.setBackgroundTintList(getColorStateList(android.R.color.holo_blue_dark));
Toast.makeText(this, "Seguimiento detenido", Toast.LENGTH_SHORT).show();
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
stepCount = (int) event.values[0];
txtStepCount.setText(String.valueOf(stepCount));
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// No se requiere implementación
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Wear Channel";
String description = "Canal de notificaciones para Wear OS";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
}
private void sendNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle("Wear OS App")
.setContentText("¡Has caminado " + stepCount + " pasos hoy!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVibrate(new long[]{0, 500, 200, 500})
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Toast.makeText(this, "Notificación enviada", Toast.LENGTH_SHORT).show();
}
@Override
protected void onPause() {
super.onPause();
if (isTracking) {
sensorManager.unregisterListener(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (isTracking && stepCounterSensor != null) {
sensorManager.registerListener(this, stepCounterSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
}🟩 8. Crear Adaptador para Lista Circular
📄 WearListAdapter.java
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class WearListAdapter extends RecyclerView.Adapter<WearListAdapter.ViewHolder> {
private List<String> items;
private OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(String item);
}
public WearListAdapter(List<String> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String item = items.get(position);
holder.textView.setText(item);
holder.itemView.setOnClickListener(v -> listener.onItemClick(item));
}
@Override
public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(android.R.id.text1);
textView.setTextColor(0xFFFFFFFF);
}
}
}🟩 9. Actividad con Lista Circular
📄 ListActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.wear.widget.WearableLinearLayoutManager;
import androidx.wear.widget.WearableRecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class ListActivity extends AppCompatActivity {
WearableRecyclerView recyclerView;
WearListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
recyclerView = findViewById(R.id.recyclerView);
// Configurar LayoutManager para pantalla curva
WearableLinearLayoutManager layoutManager = new WearableLinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setEdgeItemsCenteringEnabled(true);
// Crear lista de items
List<String> items = new ArrayList<>();
items.add("Correr");
items.add("Caminar");
items.add("Ciclismo");
items.add("Natación");
items.add("Yoga");
items.add("Gimnasio");
items.add("Fútbol");
items.add("Baloncesto");
// Configurar adaptador
adapter = new WearListAdapter(items, item ->
Toast.makeText(this, "Seleccionado: " + item, Toast.LENGTH_SHORT).show()
);
recyclerView.setAdapter(adapter);
}
}🟩 10. Configurar AndroidManifest.xml
📄 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Permisos para Wear OS -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Declarar que es una app Wear OS -->
<uses-feature android:name="android.hardware.type.watch" />
<!-- Sensor de pasos -->
<uses-feature
android:name="android.hardware.sensor.stepdetector"
android:required="false" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.DeviceDefault"
tools:targetApi="26">
<!-- Metadata para identificar como app Wear -->
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
<!-- Actividad Principal -->
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Actividad de Lista -->
<activity
android:name=".ListActivity"
android:exported="false"
android:label="Actividades"
android:theme="@android:style/Theme.DeviceDefault" />
</application>
</manifest>🟩 11. Sensores Disponibles en Wear OS
| Sensor | Descripción |
|---|---|
TYPE_STEP_COUNTER | Contador de pasos acumulados |
TYPE_STEP_DETECTOR | Detecta cada paso individual |
TYPE_HEART_RATE | Monitor de frecuencia cardÃaca |
TYPE_ACCELEROMETER | Acelerómetro para movimiento |
TYPE_GYROSCOPE | Giroscopio para rotación |
TYPE_AMBIENT_TEMPERATURE | Temperatura ambiente |
TYPE_PRESSURE | Presión barométrica |
🟩 12. Crear Complicación para Watch Face
📄 ComplicationService.java
import android.app.PendingIntent;
import android.content.Intent;
import androidx.wear.watchface.complications.data.ComplicationData;
import androidx.wear.watchface.complications.data.ComplicationType;
import androidx.wear.watchface.complications.data.PlainComplicationText;
import androidx.wear.watchface.complications.data.ShortTextComplicationData;
import androidx.wear.watchface.complications.datasource.ComplicationDataSourceService;
import androidx.wear.watchface.complications.datasource.ComplicationRequest;
public class StepComplicationService extends ComplicationDataSourceService {
@Override
public void onComplicationRequest(ComplicationRequest request, ComplicationRequestListener listener) {
// Obtener conteo de pasos (simulado)
int steps = 5432;
// Crear Intent para abrir la app
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_IMMUTABLE
);
// Crear complicación
ShortTextComplicationData complicationData = new ShortTextComplicationData.Builder(
PlainComplicationText.Builder(steps + " pasos").build(),
PlainComplicationText.Builder("Pasos").build()
)
.setTapAction(pendingIntent)
.build();
listener.onComplicationData(complicationData);
}
@Override
public void onComplicationActivated(int complicationInstanceId, ComplicationType type) {
// Complicación activada
}
@Override
public void onComplicationDeactivated(int complicationInstanceId) {
// Complicación desactivada
}
@Override
public ComplicationType[] getSupportedComplicationTypes(int complicationInstanceId) {
return new ComplicationType[]{
ComplicationType.SHORT_TEXT,
ComplicationType.LONG_TEXT
};
}
}🟩 13. Configurar Emulador Wear OS
- Abre AVD Manager en Android Studio
- Clic en Create Virtual Device
- Selecciona categorÃa Wear OS
- Elige un dispositivo (Wear OS Square o Round)
- Selecciona API 30 o superior
- Finaliza y ejecuta el emulador
▶️ Cómo Ejecutar tu Aplicación
- Abre Android Studio
- Conecta tu smartwatch o inicia el emulador Wear OS
- Presiona Run para ejecutar el proyecto
- La aplicación se instalará en tu dispositivo Wear OS
- Verás la interfaz optimizada para smartwatch funcionando
🧪 Resultado Final
Tu aplicación Wear OS mostrará:
- Interfaz adaptada a pantallas circulares y cuadradas
- Contador de pasos en tiempo real
- Botones optimizados para smartwatch
- Notificaciones con vibración
- Lista circular con desplazamiento curvo
- Sensores de actividad fÃsica funcionando
📥 Descargar Proyecto de Ejemplo
Puedes descargar el proyecto completo desde el siguiente enlace:
👉 Estamos trabajando en ello!
🙌 Gracias por Visitar mi Blog
Si este tutorial te fue útil:
✔️ Compártelo
✔️ Déjame un comentario
✔️ SÃgueme para más contenido sobre Android y programación
¡Estoy aquà para ayudarte!
❓ Preguntas Frecuentes (FAQ)
1. ¿Puedo desarrollar para Wear OS sin tener un smartwatch fÃsico?
SÃ, Android Studio incluye emuladores de Wear OS que simulan tanto pantallas circulares como cuadradas para desarrollo y testing.
2. ¿Qué diferencias hay entre una app normal de Android y una de Wear OS?
Las apps de Wear OS tienen interfaces más compactas, diseños adaptados a pantallas pequeñas y circulares, enfoque en notificaciones rápidas y acceso a sensores especÃficos de wearables.
3. ¿Puedo sincronizar datos entre mi app móvil y mi app Wear OS?
SÃ, puedes usar la Wearable Data Layer API de Google Play Services para sincronizar datos entre dispositivos móviles y smartwatches.
4. ¿Qué sensores están disponibles en Wear OS?
Los smartwatches Wear OS incluyen sensores como contador de pasos, monitor de frecuencia cardÃaca, acelerómetro, giroscopio, GPS y algunos modelos incluyen sensores adicionales de salud.

No hay comentarios:
Publicar un comentario