Le SDK Android vous permet d'accéder aux différentes entrées et capteurs disponibles avec Glass EE2. Cette page offre un aperçu des fonctionnalités disponibles, des détails de mise en œuvre et des conseils utiles.
Gestes pour appuyer
Vous pouvez utiliser le SDK Android pour permettre l'accès aux données brutes depuis le pavé tactile Glass. Pour ce faire, elles utilisent un détecteur de gestes qui détecte automatiquement les gestes les plus courants sur Glass, comme les gestes d'appui, de balayage ou de défilement.
Vous pouvez également utiliser ce détecteur dans vos applications pour tenir compte des gestes d'appui, de balayage vers l'avant, de balayage vers le bas et vers le bas. Cette fonctionnalité est semblable aux appareils Glass précédents.
Il est préférable d'utiliser ces gestes de différentes manières:
- Appuyer: confirmez ou appuyez sur Entrée.
- Balayez l'écran vers l'avant, balayez l'écran vers l'arrière: parcourez les cartes et les écrans.
- Balayer vers le bas : "Retour"ou"Quitter".
Pour en savoir plus sur l'implémentation, consultez l'exemple de détecteur de geste.
Détecter des gestes avec le détecteur de gestes Android
L'GestureDetector Android vous permet de détecter des gestes simples et complexes, tels que ceux qui utilisent plusieurs doigts ou font défiler des éléments.
Détecter les gestes d'activité
Détectez les gestes au niveau de l'activité uniquement lorsqu'il n'est pas nécessaire de contrôler les parties de l'interface utilisateur concernées.
Par exemple, si vous souhaitez afficher un menu lorsqu'un utilisateur appuie sur le pavé tactile, quelle que soit la vue sélectionnée, gérez l'élément MotionEvent dans l'activité.
Voici un exemple de détection des gestes au niveau de l'activité qui utilise GestureDetector et met en œuvre GestureDetector.OnGestureListener pour traiter les expressions faciales reconnues, qui sont ensuite traitées et traduites comme suit:
TAPSWIPE_FORWARDSWIPE_BACKWARDSWIPE_UPSWIPE_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 pouvoir utiliser la détection des gestes au niveau de l'activité, vous devez effectuer les tâches suivantes:
- Ajoutez la déclaration suivante à votre fichier manifeste, dans la déclaration d'application. Cela permet à votre application de recevoir le
MotionEventdans l'activité :<application> <!-- Copy below declaration into your manifest file --> <meta-data android:name="com.google.android.glass.TouchEnabledApplication" android:value="true" /> </application>
- Remplacez la méthode d'activité
dispatchTouchEvent(motionEvent)pour transmettre les événements de mouvement à la méthodeonTouchEvent(motionEvent)du détecteur de gestes. - Implémentez
GlassGestureDetector.OnGestureListenerdans 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 compatible avec les sources audio de base.
Le traitement des signaux avancé est intégré aux sources audio suivantes:
Reconnaissance vocale
Glass Enterprise Edition 2 propose une implémentation native pour la reconnaissance vocale. Cette option n'est disponible qu'en anglais.
L'interface de reconnaissance vocale attend que l'utilisateur parle, puis renvoie le texte transcrit. Pour démarrer l'activité, procédez comme suit:
- Appelez
startActivityForResult()avec l'intentACTION_RECOGNIZE_SPEECH. Les options d'intent supplémentaires suivantes sont disponibles lorsque vous démarrez l'activité : - Ignorez le rappel
onActivityResult()pour recevoir le texte transcrit de l'intentEXTRA_RESULTSsupplémentaire, 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.
Limiter les résultats aux mots clés
La reconnaissance vocale sur Glass peut être biaisée pour une liste de mots clés. La pondération augmente la précision de la reconnaissance des mots clés. Pour activer la pondération des mots clés, utilisez le code suivant:
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 pouvez créer des commandes vocales avec les API de menu Android standards, mais les utilisateurs peuvent appeler les éléments de menu à l'aide de commandes vocales au lieu d'appuyer.
Pour activer les commandes vocales pour une activité précise, procédez comme suit:
- 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. - Demandez l'autorisation
RECORD_AUDIOdans votre application. - Ignorez
onCreatePanelMenu()et gonflez une ressource de menu. - Ignorez
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>
Lisez l'exemple d'application de prise de notes pour obtenir un exemple complet.
Actualisation de la liste de commandes vocales
Vous pouvez actualiser 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 reload-voice-commands:
Kotlin
sendBroadcast(Intent("reload-voice-commands"))
Java
sendBroadcast(new Intent("reload-voice-commands"));
Activer et désactiver les commandes vocales dans l'environnement d'exécution
Vous pouvez activer et désactiver les commandes vocales pendant l'exécution. Pour ce faire, renvoyez une valeur appropriée à partir de la méthode onCreatePanelMenu(), comme suit:
- Définissez la valeur sur
truepour l'activer. - Définissez la valeur sur
falsepour la désactiver.
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 contenant l'expression reconnue pour le débogage.
- Une superposition d'interface utilisateur s'affiche lorsqu'une commande non reconnue est détectée, comme illustré ci-dessous:
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'exemple d'application permettant de recharger les commandes vocales.
Synthèse vocale
La fonctionnalité de synthèse vocale convertit le texte numérique en sortie vocale synthétisée. Pour en savoir plus, consultez la documentation TextToSpeech d'Android Developers.
Le moteur Google Text-to-Speech est installé sur Glass EE2. Il s'agit du moteur de synthèse vocale par défaut qui fonctionne hors connexion.
Les paramètres régionaux suivants sont intégrés au 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 Soudanais Suédois Tamoul Télougou Thaï Turc Ukrainien Vietnamien |
Caméra
Glass Enterprise Edition 2 est équipé d'une caméra à mise au point fixe de 8 mégapixels avec une ouverture de f/2,4, des proportions de 4:3 et un champ de vision de 83° en diagonale (71° x 57° en orientation paysage). Nous vous recommandons d'utiliser l'API standard 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.
Elle peut être gérée comme une action de clavier standard, et elle peut être identifiée par le code-clé KeyEvent#KEYCODE_CAMERA.
À compter de la mise à jour de l'OS OPM1.200313.001, les intents ayant les actions suivantes sont envoyés à partir de l'application de lancement:
MediaStore#ACTION_IMAGE_CAPTUREsur le bouton court de l'appareil photo.MediaStore#ACTION_VIDEO_CAPTUREappuyez de manière prolongée sur le bouton de l'appareil photo.
Capteurs
Différents capteurs sont disponibles pour les développeurs qui développent des applications dans Glass EE2.
Les capteurs Android standards suivants sont compatibles avec Glass:
-
TYPE_ACCELEROMETER -
TYPE_GRAVITY -
TYPE_GYROSCOPE -
TYPE_LIGHT -
TYPE_LINEAR_ACCELERATION -
TYPE_MAGNETIC_FIELD TYPE_ORIENTATION(obsolète)-
TYPE_ROTATION_VECTOR
Les capteurs Android suivants ne sont pas compatibles avec Glass:
Le système de coordonnées du capteur Glass est illustré dans l'illustration suivante. Par rapport à l'écran Glass. Pour en savoir plus, consultez la section Système de coordonnées du capteur.
L'accéléromètre, le gyroscope et le magnétomètre sont situés sur la sonde optique de l'appareil Glass, que les utilisateurs font pivoter pour aligner l'appareil sur leur champ de vision. Il n'est pas possible de mesurer directement l'angle du pod optique. Il est donc important de tenir compte de ce point lorsque vous utilisez des angles de ces capteurs pour des applications telles qu'une direction de boussole.
Pour prolonger l'autonomie de la batterie, n'écoutez les capteurs que lorsque vous en avez besoin. Lorsque vous décidez de lancer ou d'arrêter l'écoute des capteurs, tenez compte des besoins et du cycle de vie de l'application.
Les rappels d'événement des capteurs s'exécutent sur le thread UI. Par conséquent, traitez les événements et renvoyez-les aussi rapidement que possible. Si le traitement prend trop de temps, placez les événements de capteurs dans une file d'attente et utilisez un thread d'arrière-plan pour les gérer.
La fréquence de 50 Hz est souvent suffisante 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 doté d'un module GPS et ne fournit pas la position de l'utilisateur. Toutefois, les services de localisation sont mis en œuvre, ce qui est nécessaire pour afficher la liste des réseaux Wi-Fi et des appareils Bluetooth à proximité.
Si votre application dispose des droits 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, celle-ci doit pouvoir modifier ces paramètres à votre place.