Entrées et capteurs

Le SDK Android vous permet d'accéder aux différentes entrées et capteurs disponibles avec Glass EE2. Cette page vous présente les fonctionnalités disponibles, des informations sur l'implémentation et des conseils utiles.

Gestes pour appuyer

Vous pouvez utiliser le SDK Android pour activer l'accès aux données brutes du pavé tactile Glass. Pour ce faire, un détecteur de gestes détecte automatiquement les gestes courants sur Glass, comme appuyer, balayer et faire défiler.

Vous pouvez également utiliser ce détecteur de gestes dans vos applications pour tenir compte des gestes d'appui, de balayage vers l'avant, de balayage vers l'arrière et de balayage vers le bas. Cela ressemble aux appareils Glass précédents.

Il est préférable d'utiliser ces gestes de la manière suivante :

  • Appuyer : confirmer ou saisir.
  • Balayer vers l'avant, balayer vers l'arrière : parcourez les fiches et les écrans.
  • Balayer l'écran vers le bas : revenir en arrière ou quitter.

Pour en savoir plus sur l'implémentation, consultez l'exemple de détecteur de gestes.

Détecter les gestes avec le détecteur de gestes Android

L'GestureDetector Android vous permet de détecter des gestes simples et complexes, comme ceux qui utilisent plusieurs doigts ou le défilement.

Détecter les gestes au niveau de l'activité

Détectez les gestes au niveau de l'activité uniquement lorsque la partie de votre UI sélectionnée n'a pas d'importance. Par exemple, si vous souhaitez afficher un menu lorsqu'un utilisateur appuie sur le pavé tactile, quel que soit l'affichage sélectionné, gérez MotionEvent dans l'activité.

Voici un exemple de détection de gestes au niveau de l'activité qui utilise GestureDetector et implémente GestureDetector.OnGestureListener pour traiter les gestes reconnus, qui sont ensuite gérés et traduits comme suit :

  • TAP
  • SWIPE_FORWARD
  • SWIPE_BACKWARD
  • SWIPE_UP
  • SWIPE_DOWN

Kotlin

class GlassGestureDetector(context: Context, private val onGestureListener: OnGestureListener) :
    GestureDetector.OnGestureListener {

    private val gestureDetector = GestureDetector(context, this)

    enum class Gesture {
        TAP,
        SWIPE_FORWARD,
        SWIPE_BACKWARD,
        SWIPE_UP,
        SWIPE_DOWN
    }

    interface OnGestureListener {
        fun onGesture(gesture: Gesture): Boolean
    }

    fun onTouchEvent(motionEvent: MotionEvent): Boolean {
        return gestureDetector.onTouchEvent(motionEvent)
    }

    override fun onDown(e: MotionEvent): Boolean {
        return false
    }

    override fun onShowPress(e: MotionEvent) {}

    override fun onSingleTapUp(e: MotionEvent): Boolean {
        return onGestureListener.onGesture(Gesture.TAP)
    }

    override fun onScroll(
        e1: MotionEvent,
        e2: MotionEvent,
        distanceX: Float,
        distanceY: Float
    ): Boolean {
        return false
    }

    override fun onLongPress(e: MotionEvent) {}

    /**
     * Swipe detection depends on the:
     * - movement tan value,
     * - movement distance,
     * - movement velocity.
     *
     * To prevent unintentional SWIPE_DOWN and SWIPE_UP gestures, they are detected if movement
     * angle is only between 60 and 120 degrees.
     * Any other detected swipes, will be considered as SWIPE_FORWARD and SWIPE_BACKWARD, depends
     * on deltaX value sign.
     *
     * ______________________________________________________________
     * |                     \        UP         /                    |
     * |                       \               /                      |
     * |                         60         120                       |
     * |                           \       /                          |
     * |                             \   /                            |
     * |  BACKWARD  <-------  0  ------------  180  ------>  FORWARD  |
     * |                             /   \                            |
     * |                           /       \                          |
     * |                         60         120                       |
     * |                       /               \                      |
     * |                     /       DOWN        \                    |
     * --------------------------------------------------------------
     */
    override fun onFling(
        e1: MotionEvent,
        e2: MotionEvent,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        val deltaX = e2.x - e1.x
        val deltaY = e2.y - e1.y
        val tan =
            if (deltaX != 0f) abs(deltaY / deltaX).toDouble() else java.lang.Double.MAX_VALUE

        return if (tan > TAN_60_DEGREES) {
            if (abs(deltaY) < SWIPE_DISTANCE_THRESHOLD_PX || Math.abs(velocityY) < SWIPE_VELOCITY_THRESHOLD_PX) {
                false
            } else if (deltaY < 0) {
                onGestureListener.onGesture(Gesture.SWIPE_UP)
            } else {
                onGestureListener.onGesture(Gesture.SWIPE_DOWN)
            }
        } else {
            if (Math.abs(deltaX) < SWIPE_DISTANCE_THRESHOLD_PX || Math.abs(velocityX) < SWIPE_VELOCITY_THRESHOLD_PX) {
                false
            } else if (deltaX < 0) {
                onGestureListener.onGesture(Gesture.SWIPE_FORWARD)
            } else {
                onGestureListener.onGesture(Gesture.SWIPE_BACKWARD)
            }
        }
    }

    companion object {

        private const val SWIPE_DISTANCE_THRESHOLD_PX = 100
        private const val SWIPE_VELOCITY_THRESHOLD_PX = 100
        private val TAN_60_DEGREES = tan(Math.toRadians(60.0))
    }
}

Java

  public class GlassGestureDetector implements GestureDetector.OnGestureListener {

   enum Gesture {
     TAP,
     SWIPE_FORWARD,
     SWIPE_BACKWARD,
     SWIPE_UP,
     SWIPE_DOWN,
   }

   interface OnGestureListener {
     boolean onGesture(Gesture gesture);
   }

   private static final int SWIPE_DISTANCE_THRESHOLD_PX = 100;
   private static final int SWIPE_VELOCITY_THRESHOLD_PX = 100;
   private static final double TAN_60_DEGREES = Math.tan(Math.toRadians(60));

   private GestureDetector gestureDetector;
   private OnGestureListener onGestureListener;

   public GlassGestureDetector(Context context, OnGestureListener onGestureListener) {
     gestureDetector = new GestureDetector(context, this);
     this.onGestureListener = onGestureListener;
   }

   public boolean onTouchEvent(MotionEvent motionEvent) {
     return gestureDetector.onTouchEvent(motionEvent);
   }

   @Override
   public boolean onDown(MotionEvent e) {
     return false;
   }

   @Override
   public void onShowPress(MotionEvent e) {
   }

   @Override
   public boolean onSingleTapUp(MotionEvent e) {
     return onGestureListener.onGesture(Gesture.TAP);
   }

   @Override
   public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
     return false;
   }

   @Override
   public void onLongPress(MotionEvent e) {
   }

   /**
    * Swipe detection depends on the:
    * - movement tan value,
    * - movement distance,
    * - movement velocity.
    *
    * To prevent unintentional SWIPE_DOWN and SWIPE_UP gestures, they are detected if movement
    * angle is only between 60 and 120 degrees.
    * Any other detected swipes, will be considered as SWIPE_FORWARD and SWIPE_BACKWARD, depends
    * on deltaX value sign.
    *
    *           ______________________________________________________________
    *          |                     \        UP         /                    |
    *          |                       \               /                      |
    *          |                         60         120                       |
    *          |                           \       /                          |
    *          |                             \   /                            |
    *          |  BACKWARD  <-------  0  ------------  180  ------>  FORWARD  |
    *          |                             /   \                            |
    *          |                           /       \                          |
    *          |                         60         120                       |
    *          |                       /               \                      |
    *          |                     /       DOWN        \                    |
    *           --------------------------------------------------------------
    */
   @Override
   public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
     final float deltaX = e2.getX() - e1.getX();
     final float deltaY = e2.getY() - e1.getY();
     final double tan = deltaX != 0 ? Math.abs(deltaY/deltaX) : Double.MAX_VALUE;

     if (tan > TAN_60_DEGREES) {
       if (Math.abs(deltaY) < SWIPE_DISTANCE_THRESHOLD_PX || Math.abs(velocityY) < SWIPE_VELOCITY_THRESHOLD_PX) {
         return false;
       } else if (deltaY < 0) {
         return onGestureListener.onGesture(Gesture.SWIPE_UP);
       } else {
         return onGestureListener.onGesture(Gesture.SWIPE_DOWN);
       }
     } else {
       if (Math.abs(deltaX) < SWIPE_DISTANCE_THRESHOLD_PX || Math.abs(velocityX) < SWIPE_VELOCITY_THRESHOLD_PX) {
         return false;
       } else if (deltaX < 0) {
         return onGestureListener.onGesture(Gesture.SWIPE_FORWARD);
       } else {
         return onGestureListener.onGesture(Gesture.SWIPE_BACKWARD);
       }
     }
   }
  }

Exemple d'utilisation

Pour utiliser la détection de gestes au niveau de l'activité, vous devez effectuer les tâches suivantes :

  1. Ajoutez la déclaration suivante à votre fichier manifeste, dans la déclaration de l'application. Cela permet à votre application de recevoir le MotionEvent dans l'activité :
    <application>
    <!-- Copy below declaration into your manifest file -->
    <meta-data
      android:name="com.google.android.glass.TouchEnabledApplication"
      android:value="true" />
    </application>
  2. Remplacez la méthode dispatchTouchEvent(motionEvent) de l'activité pour transmettre les événements de mouvement à la méthode onTouchEvent(motionEvent) du détecteur de gestes.
  3. Implémentez GlassGestureDetector.OnGestureListener dans votre activité.

Voici un exemple de détecteur de gestes au niveau de l'activité :

Kotlin

class MainAcvitiy : AppCompatActivity(), GlassGestureDetector.OnGestureListener {

    private lateinit var glassGestureDetector: GlassGestureDetector

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        glassGestureDetector = GlassGestureDetector(this, this)
    }

    override fun onGesture(gesture: GlassGestureDetector.Gesture): Boolean {
        when (gesture) {
            TAP ->
                // Response for TAP gesture
                return true
            SWIPE_FORWARD ->
                // Response for SWIPE_FORWARD gesture
                return true
            SWIPE_BACKWARD ->
                // Response for SWIPE_BACKWARD gesture
                return true
            else -> return false
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        return if (glassGestureDetector.onTouchEvent(ev)) {
            true
        } else super.dispatchTouchEvent(ev)
    }
}

Java

  public class MainActivity extends AppCompatActivity implements OnGestureListener {

   private GlassGestureDetector glassGestureDetector;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     glassGestureDetector = new GlassGestureDetector(this, this);
   }

   @Override
   public boolean onGesture(Gesture gesture) {
     switch (gesture) {
       case TAP:
         // Response for TAP gesture
         return true;
       case SWIPE_FORWARD:
         // Response for SWIPE_FORWARD gesture
         return true;
       case SWIPE_BACKWARD:
         // Response for SWIPE_BACKWARD gesture
         return true;
       default:
         return false;
     }
   }

   @Override
   public boolean dispatchTouchEvent(MotionEvent ev) {
     if (glassGestureDetector.onTouchEvent(ev)) {
       return true;
     }
     return super.dispatchTouchEvent(ev);
   }
  }

Entrée audio

Glass Enterprise Edition 2 est un appareil standard basé sur AOSP qui est compatible avec les sources audio de base.

Le traitement avancé du signal est implémenté pour les sources audio suivantes :

Reconnaissance vocale

Glass Enterprise Edition 2 est compatible avec une implémentation native pour la reconnaissance vocale. Cette fonctionnalité n'est disponible qu'en anglais.

Image de la reconnaissance vocale de Glass.

L'UI de reconnaissance vocale attend que les utilisateurs parlent, puis renvoie le texte transcrit une fois qu'ils ont terminé. Pour démarrer l'activité :

  1. Appelez startActivityForResult() avec l'intention ACTION_RECOGNIZE_SPEECH. Les extras d'intent suivants sont acceptés lorsque vous démarrez l'activité :
  2. Remplacez le rappel onActivityResult() pour recevoir le texte transcrit de l'extra d'intent EXTRA_RESULTS, comme indiqué dans l'exemple de code suivant. Ce rappel est appelé lorsque l'utilisateur a fini de parler.

Kotlin

private const val SPEECH_REQUEST = 109

private fun displaySpeechRecognizer() {
    val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
    startActivityForResult(intent, SPEECH_REQUEST)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
        val results: List<String>? =
            data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
        val spokenText = results?.get(0)
        // Do something with spokenText.
    }
    super.onActivityResult(requestCode, resultCode, data)
}

Java

private static final int SPEECH_REQUEST = 109;

private void displaySpeechRecognizer() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    startActivityForResult(intent, SPEECH_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
        Intent data) {
    if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
        List<String> results = data.getStringArrayListExtra(
                RecognizerIntent.EXTRA_RESULTS);
        String spokenText = results.get(0);
        // Do something with spokenText.
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Pour en savoir plus sur l'implémentation, consultez l'exemple d'application de reconnaissance vocale.

Favoriser les mots clés

La reconnaissance vocale sur Glass peut être biaisée pour une liste de mots clés. Le biasing améliore la précision de la reconnaissance des mots clés. Pour activer le biais pour les mots clés, utilisez ce qui suit :

Kotlin

val keywords = arrayOf("Example", "Biasing", "Keywords")

val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra("recognition-phrases", keywords)

startActivityForResult(intent, SPEECH_REQUEST)

Java

final String[] keywords = {"Example", "Biasing", "Keywords"};

Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra("recognition-phrases", keywords);

startActivityForResult(intent, SPEECH_REQUEST);

Commandes vocales

Les commandes vocales permettent aux utilisateurs d'effectuer des actions à partir d'activités. Vous créez des commandes vocales avec les API de menu Android standards, mais les utilisateurs peuvent appeler les éléments de menu avec des commandes vocales au lieu d'appuyer sur l'écran.

Pour activer les commandes vocales pour une activité spécifique, procédez comme suit :

  1. Appelez getWindow().requestFeature(FEATURE_VOICE_COMMANDS) dans l'activité souhaitée pour activer les commandes vocales. Lorsque cette fonctionnalité est activée, l'icône du micro  apparaît en bas à gauche de l'écran chaque fois que cette activité est sélectionnée.
  2. Demandez l'autorisation RECORD_AUDIO dans votre application.
  3. Remplacez onCreatePanelMenu() et développez une ressource de menu.
  4. Remplacez onContextItemSelected() pour gérer les commandes vocales détectées.

Kotlin

class VoiceCommandsActivity : AppCompatActivity() {

    companion object {
        const val FEATURE_VOICE_COMMANDS = 14
        const val REQUEST_PERMISSION_CODE = 200
        val PERMISSIONS = arrayOf(Manifest.permission.RECORD_AUDIO)
        val TAG = VoiceCommandsActivity::class.java.simpleName
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.requestFeature(FEATURE_VOICE_COMMANDS)
        setContentView(R.layout.activity_voice_commands)

        // Requesting permissions to enable voice commands menu
        ActivityCompat.requestPermissions(
            this,
            PERMISSIONS,
            REQUEST_PERMISSION_CODE
        )
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == REQUEST_PERMISSION_CODE) {
            for (result in grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "Permission denied. Voice commands menu is disabled.")
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }

    override fun onCreatePanelMenu(featureId: Int, menu: Menu): Boolean {
        menuInflater.inflate(R.menu.voice_commands_menu, menu)
        return true
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            // Handle selected menu item
            R.id.edit -> {
                // Handle edit action
                true
            }
            else -> super.onContextItemSelected(item)
        }
    }
}

Java

public class VoiceCommandsActivity extends AppCompatActivity {

  private static final String TAG = VoiceCommandsActivity.class.getSimpleName();
  private static final int FEATURE_VOICE_COMMANDS = 14;
  private static final int REQUEST_PERMISSION_CODE = 200;
  private static final String[] PERMISSIONS = new String[]{Manifest.permission.RECORD_AUDIO};

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(FEATURE_VOICE_COMMANDS);
    setContentView(R.layout.activity_voice_commands);

    // Requesting permissions to enable voice commands menu
    ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSION_CODE);
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_PERMISSION_CODE) {
      for (int result : grantResults) {
        if (result != PackageManager.PERMISSION_GRANTED) {
          Log.d(TAG, "Permission denied. Voice commands menu is disabled.");
        }
      }
    } else {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
  }

  @Override
  public boolean onCreatePanelMenu(int featureId, @NonNull Menu menu) {
    getMenuInflater().inflate(R.menu.voice_commands_menu, menu);
    return true;
  }

  @Override
  public boolean onContextItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()) {
      // Handle selected menu item
      case R.id.edit:
        // Handle edit action
        return true;
      default:
        return super.onContextItemSelected(item);
    }
  }
}

Voici un exemple de ressource de menu utilisée par l'activité précédente :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_delete"
        android:title="@string/delete"/>
    <item
        android:id="@+id/edit"
        android:icon="@drawable/ic_edit"
        android:title="@string/edit"/>
    <item
        android:id="@+id/find"
        android:icon="@drawable/ic_search"
        android:title="@string/find"/>
</menu>

Pour obtenir un exemple complet, consultez l'application de prise de notes exemple.

Rechargement de la liste des commandes vocales

Vous pouvez recharger dynamiquement la liste des commandes vocales. Pour ce faire, remplacez la ressource menu dans la méthode onCreatePanelMenu() ou modifiez l'objet de menu dans la méthode onPreparePanel(). Pour appliquer les modifications, appelez la méthode invalidateOptionsMenu().

Kotlin

private val options = mutableListOf<String>()

fun onPreparePanel(featureId: Int, view: View?, menu: Menu): Boolean {
  if (featureId != FEATURE_VOICE_COMMANDS) {
    return super.onCreatePanelMenu(featureId, menu)
  }
  for (optionTitle in options) {
    menu.add(optionTitle)
  }
  return true
}

/**
 * Method showing example implementation of voice command list modification
 *
 * If you call [Activity.invalidateOptionsMenu] method, voice command  list will be
 * reloaded (onCreatePanelMenu and onPreparePanel methods will be called).
 */
private fun modifyVoiceCommandList() {
  options.add("Delete")
  options.add("Play")
  options.add("Pause")
  invalidateOptionsMenu()
}

Java

private final List<String> options = new ArrayList<>();

@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
  if (featureId != FEATURE_VOICE_COMMANDS) {
    return super.onCreatePanelMenu(featureId, menu);
  }
  for (String optionTitle : options) {
    menu.add(optionTitle);
  }
  return true;
}

/**
 * Method showing example implementation of voice command list modification
 *
 * If you call {@link Activity#invalidateOptionsMenu()} method, voice command  list will be
 * reloaded (onCreatePanelMenu and onPreparePanel methods will be called).
 */
private void modifyVoiceCommandList() {
  options.add("Delete");
  options.add("Play");
  options.add("Pause");
  invalidateOptionsMenu();
}

Solution AppCompatActivity

Pour recharger une liste de commandes vocales dans une activité qui étend AppCompatActivity, utilisez la méthode sendBroadcast() avec l'action d'intent reload-voice-commands :

Kotlin

sendBroadcast(Intent("reload-voice-commands"))

Java

sendBroadcast(new Intent("reload-voice-commands"));

Activer et désactiver les commandes vocales au moment de l'exécution

Vous pouvez activer et désactiver les commandes vocales au moment de l'exécution. Pour ce faire, renvoyez une valeur appropriée à partir de la méthode onCreatePanelMenu() comme suit :

  • Définissez la valeur sur true pour activer la fonctionnalité.
  • Définissez la valeur sur false pour désactiver la fonctionnalité.

Mode débogage

Pour activer le mode débogage pour les commandes vocales, appelez getWindow().requestFeature(FEATURE_DEBUG_VOICE_COMMANDS) dans l'activité souhaitée. Le mode débogage active les fonctionnalités suivantes :

  • Logcat contient le journal avec l'expression reconnue pour le débogage.
  • Une superposition d'UI s'affiche lorsqu'une commande non reconnue est détectée, comme illustré ci-dessous :
  • Image de commande vocale non reconnue par Glass.

Kotlin

class VoiceCommandsActivity : AppCompatActivity() {

    companion object {
        const val FEATURE_VOICE_COMMANDS = 14
        const val FEATURE_DEBUG_VOICE_COMMANDS = 15
        const val REQUEST_PERMISSION_CODE = 200
        val PERMISSIONS = arrayOf(Manifest.permission.RECORD_AUDIO)
        val TAG = VoiceCommandsActivity::class.java.simpleName
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.requestFeature(FEATURE_VOICE_COMMANDS)
        window.requestFeature(FEATURE_DEBUG_VOICE_COMMANDS)
        setContentView(R.layout.activity_voice_commands)

        // Requesting permissions to enable voice commands menu
        ActivityCompat.requestPermissions(
            this,
            PERMISSIONS,
            REQUEST_PERMISSION_CODE
        )
    }
    .
    .
    .
}

Java

public class VoiceCommandsActivity extends AppCompatActivity {

  private static final String TAG = VoiceCommandsActivity.class.getSimpleName();
  private static final int FEATURE_VOICE_COMMANDS = 14;
  private static final int FEATURE_DEBUG_VOICE_COMMANDS = 15;
  private static final int REQUEST_PERMISSION_CODE = 200;
  private static final String[] PERMISSIONS = new String[]{Manifest.permission.RECORD_AUDIO};

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(FEATURE_VOICE_COMMANDS);
    getWindow().requestFeature(FEATURE_DEBUG_VOICE_COMMANDS);
    setContentView(R.layout.activity_voice_commands);

    // Requesting permissions to enable voice commands menu
    ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSION_CODE);
  }
  .
  .
  .
}

Pour en savoir plus sur l'implémentation, consultez l'application de rechargement des exemples de commandes vocales.

Synthèse vocale

La fonctionnalité Text-to-Speech convertit le texte numérique en sortie vocale synthétisée. Pour en savoir plus, consultez la documentation Android Developers TextToSpeech.

Le moteur de synthèse vocale Google est installé sur Glass EE2. Il est défini comme moteur TTS par défaut et fonctionne hors connexion.

Les paramètres régionaux suivants sont fournis avec le moteur de synthèse vocale Google :

Bengali
Chinois mandarin
Tchèque
Danois
Allemand
Grec
Anglais
Espagnol
Estonien
Finnois
Français
Gujarati
Hindi
Hongrois
Indonésien
Italien
Japonais
Javanais
Austronésien
Austroasiatique
Kannada
Coréen
Malayalam
Norvégien
Néerlandais
Polonais
Portugais
Russe
Slovaque
Soundanais
Suédois
Tamoul
Télougou
Thaï
Turc
Ukrainien
Vietnamien

Appareil photo

Glass Enterprise Edition 2 est équipé d'une caméra de 8 mégapixels à mise au point fixe, avec une ouverture de f/2.4, un format de capteur de 4:3 et un champ de vision diagonal de 83° (71° x 57° en mode paysage). Nous vous recommandons d'utiliser les API standards CameraX ou Camera2.

Pour en savoir plus sur l'implémentation, consultez l'exemple d'application d'appareil photo.

Bouton de l'appareil photo

Le bouton de l'appareil photo est le bouton physique situé sur la charnière de l'appareil Glass Enterprise Edition 2. Il peut être géré comme une action de clavier standard et peut être identifié par le code de touche KeyEvent#KEYCODE_CAMERA.

Depuis la mise à jour de l'OS OPM1.200313.001, les intents avec les actions suivantes sont envoyés depuis l'application Launcher :

Capteurs

Les développeurs ont accès à différents capteurs lorsqu'ils développent des applications dans Glass EE2.

Les capteurs Android standards suivants sont compatibles avec Glass :

Les capteurs Android suivants ne sont pas compatibles avec Glass :

Le système de coordonnées du capteur Glass est illustré ci-dessous. Elle est relative à l'écran Glass. Pour en savoir plus, consultez Système de coordonnées du capteur.

Le système de coordonnées du capteur Glass est illustré ici, par rapport à l&#39;écran Glass.

L'accéléromètre, le gyroscope et le magnétomètre se trouvent sur le module optique de l'appareil Glass, que les utilisateurs font pivoter pour aligner l'appareil sur leur vue. Vous ne pouvez pas mesurer directement l'angle du boîtier optique. Tenez-en compte lorsque vous utilisez les angles de ces capteurs pour des applications, comme un cap de boussole.

Pour préserver l'autonomie de la batterie, n'écoutez les capteurs que lorsque vous en avez besoin. Tenez compte des besoins et du cycle de vie de l'application lorsque vous décidez quand commencer et arrêter d'écouter les capteurs.

Les rappels d'événements de capteur s'exécutent sur le thread UI. Par conséquent, traitez les événements et renvoyez-les le plus rapidement possible. Si le traitement prend trop de temps, placez les événements du capteur dans une file d'attente et utilisez un thread en arrière-plan pour les gérer.

Un taux d'échantillonnage de 50 Hz est souvent suffisant pour suivre les mouvements de la tête.

Pour en savoir plus sur l'utilisation des capteurs, consultez le guide du développeur Android.

Services de localisation

L'appareil Glass Enterprise Edition 2 n'est pas équipé d'un module GPS et ne fournit pas la position de l'utilisateur. Toutefois, il dispose de services de localisation, qui sont nécessaires pour afficher une liste des réseaux Wi-Fi et des appareils Bluetooth à proximité.

Si votre application dispose de privilèges de propriétaire de l'appareil, vous pouvez l'utiliser pour modifier de manière programmatique la valeur du paramètre sécurisé correspondant :

Kotlin

val devicePolicyManager = context
    .getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
if (devicePolicyManager.isDeviceOwnerApp(context.getPackageName())) {
    val componentName = ComponentName(context, MyDeviceAdmin::class.java)
    devicePolicyManager.setSecureSetting(
        componentName,
        Settings.Secure.LOCATION_MODE,
        Settings.Secure.LOCATION_MODE_SENSORS_ONLY.toString()
    )
}

Java

final DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context
    .getSystemService(Context.DEVICE_POLICY_SERVICE);
if (devicePolicyManager.isDeviceOwnerApp(context.getPackageName())) {
  final ComponentName componentName = new ComponentName(context, MyDeviceAdmin.class);
  devicePolicyManager.setSecureSetting(componentName, Settings.Secure.LOCATION_MODE,
      String.valueOf(Settings.Secure.LOCATION_MODE_SENSORS_ONLY));
}

Si vous utilisez une solution MDM tierce, elle doit pouvoir modifier ces paramètres pour vous.