Girişler ve sensörler

Android SDK, Glass EE2 ile kullanılabilen çeşitli girişlere ve sensörlere erişmenizi sağlar. Bu sayfada, kullanılabilen özellikler, uygulama ayrıntıları ve faydalı ipuçları hakkında genel bilgiler verilmektedir.

Dokunma hareketleri

Glass dokunmatik yüzeyinden gelen ham verilere erişimi etkinleştirmek için Android SDK'yı kullanabilirsiniz. Bu işlem, Glass'taki dokunma, kaydırma ve ekranı hızlıca kaydırma gibi yaygın hareketleri otomatik olarak algılayan bir hareket algılayıcı aracılığıyla gerçekleştirilir.

Dokunma, ileri kaydırma, geri kaydırma ve aşağı kaydırma işlemlerini hesaba katmak için bu hareket algılayıcıyı uygulamalarınızda da kullanabilirsiniz. Bu, önceki Glass cihazlarına benzer.

Bu hareketleri aşağıdaki şekillerde kullanmanız önerilir:

  • Dokunma: Onaylama veya girme
  • İleri kaydırma, geri kaydırma: Kartlar ve ekranlar arasında gezinme
  • Aşağı kaydırma: Geri gitme veya çıkma.

Uygulama ayrıntıları için örnek hareket algılayıcıyı inceleyin.

Android hareket dedektörüyle hareketleri algılama

Android GestureDetector, çok parmakla yapılan veya kaydırma gibi basit ve karmaşık hareketleri algılamanıza olanak tanır.

Etkinlik düzeyindeki hareketleri algılama

Kullanıcı arayüzünüzün hangi bölümünün odaklandığı önemli olmadığında hareketleri yalnızca etkinlik düzeyinde algılayın. Örneğin, hangi görünümün odaklandığına bakılmaksızın kullanıcı dokunma yüzeyine dokunduğunda bir menü açmak istiyorsanız MotionEvent öğesini etkinlik içinde işleyin.

Aşağıda, GestureDetector kullanan ve tanınan hareketleri işlemek için GestureDetector.OnGestureListener uygulayan etkinlik düzeyinde hareket algılamaya ilişkin bir örnek verilmiştir. Bu hareketler daha sonra işlenir ve aşağıdakilere çevrilir:

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

Örnek kullanım

Etkinlik düzeyinde hareket algılamayı kullanmak için aşağıdaki görevleri tamamlamanız gerekir:

  1. Aşağıdaki bildirimi manifest dosyanızdaki uygulama bildiriminin içine ekleyin. Bu, uygulamanızın etkinlikteki MotionEvent öğesini almasını sağlar:
    <application>
    <!-- Copy below declaration into your manifest file -->
    <meta-data
      android:name="com.google.android.glass.TouchEnabledApplication"
      android:value="true" />
    </application>
  2. Hareket etkinliklerini hareket algılayıcının onTouchEvent(motionEvent) yöntemine iletmek için etkinliğin dispatchTouchEvent(motionEvent) yöntemini geçersiz kılın.
  3. Etkinliğinizde GlassGestureDetector.OnGestureListener'ı uygulayın.

Aşağıda, etkinlik düzeyinde bir hareket algılayıcı örneği verilmiştir:

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

Ses girişi

Glass Enterprise Edition 2, temel ses kaynaklarını destekleyen, standart bir AOSP tabanlı cihazdır.

Aşağıdaki ses kaynaklarında gelişmiş sinyal işleme uygulanır:

Ses tanıma

Glass Enterprise Edition 2, konuşma tanıma için yerel bir uygulamayı destekler. Bu özellik yalnızca İngilizce için desteklenir.

Glass&#39;ta ses tanıma görüntüsü.

Ses tanıma kullanıcı arayüzü, kullanıcının konuşmasını bekler ve konuşma tamamlandıktan sonra transkripsiyonu yapılan metni döndürür. Etkinliği başlatmak için aşağıdaki adımları uygulayın:

  1. startActivityForResult() ile ACTION_RECOGNIZE_SPEECH amacıyla arama yapın. Etkinliği başlattığınızda aşağıdaki amaç ekstraları desteklenir:
  2. Aşağıdaki kod örneğinde gösterildiği gibi, onActivityResult() geri çağırma işlevini geçersiz kılarak EXTRA_RESULTS amaç ekstrasından transkripsiyonu yapılmış metni alın. Bu geri çağırma, kullanıcı konuşmayı bitirdiğinde çağrılır.

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

Uygulama ayrıntıları için örnek ses tanıma uygulamasını inceleyin.

Anahtar kelimeler için önyargı

Glass'taki konuşma tanıma özelliği, bir anahtar kelime listesi için önyargılı olabilir. Önyargı, anahtar kelime tanıma doğruluğunu artırır. Anahtar kelimeler için önyargıyı etkinleştirmek üzere aşağıdakileri kullanın:

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

Sesli komutlar

Sesli komutlar, kullanıcıların etkinliklerdeki işlemleri gerçekleştirmesine olanak tanır. Standart Android menü API'leriyle sesli komutlar oluşturursunuz ancak kullanıcılar menü öğelerini dokunmak yerine sesli komutlarla çağırabilir.

Belirli bir etkinlik için sesli komutları etkinleştirmek üzere aşağıdaki adımları uygulayın:

  1. Sesli komutları etkinleştirmek için istediğiniz etkinlikte getWindow().requestFeature(FEATURE_VOICE_COMMANDS) işlevini çağırın. Bu özellik etkinleştirildiğinde, bu etkinlik odaklandığında ekranın sol alt köşesinde mikrofon simgesi görünür.
  2. Uygulamanızda RECORD_AUDIO izni isteyin.
  3. Geçersiz kılma onCreatePanelMenu() ve menü kaynağını genişletme.
  4. Algılanan sesli komutları işlemek için onContextItemSelected() geçersiz kılın.

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

Aşağıda, önceki etkinlik tarafından kullanılan menü kaynağına dair bir örnek verilmiştir:

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

Eksiksiz bir örnek için örnek not alma uygulamasını inceleyin.

Sesli komut listesi yeniden yükleniyor

Sesli komut listesini dinamik olarak yeniden yükleyebilirsiniz. Bunu yapmak için menu kaynağını onCreatePanelMenu() yönteminde değiştirin veya onPreparePanel() yönteminde menü nesnesini değiştirin. Değişiklikleri uygulamak için invalidateOptionsMenu() yöntemini çağırın.

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

AppCompatActivity çözümü

AppCompatActivity öğesini genişleten bir etkinlikte sesli komut listesini yeniden yüklemek için reload-voice-commands amaç işlemiyle sendBroadcast() yöntemini kullanın:

Kotlin

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

Java

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

Çalışma zamanında sesli komutları etkinleştirme ve devre dışı bırakma

Çalışma zamanında sesli komutları etkinleştirebilir ve devre dışı bırakabilirsiniz. Bunu yapmak için onCreatePanelMenu() yönteminden aşağıdaki gibi uygun bir değer döndürün:

  • Etkinleştirmek için değeri true olarak ayarlayın.
  • Devre dışı bırakmak için değeri false olarak ayarlayın.

Hata ayıklama modu

Sesli komutlar için hata ayıklama modunu etkinleştirmek üzere istediğiniz etkinlikte getWindow().requestFeature(FEATURE_DEBUG_VOICE_COMMANDS) işlevini çağırın. Hata ayıklama modu aşağıdaki özellikleri etkinleştirir:

  • Logcat, hata ayıklama için tanınan ifadeyle ilgili günlüğü içerir.
  • Tanınmayan bir komut algılandığında kullanıcı arayüzü yer paylaşımı aşağıdaki gibi gösterilir:
  • Glass ses tanıma, tanınmayan komut resmi.

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

Uygulama ayrıntıları için örnek sesli komutlarla uygulamayı yeniden yükleme başlıklı makaleyi okuyun.

Metin okuma (TTS)

Metin okuma işlevi, dijital metni sentezlenmiş konuşma çıkışına dönüştürür. Daha fazla bilgi için Android Developers Documentation TextToSpeech'i ziyaret edin.

Glass EE2'de Google Metin Okuma motoru yüklüdür. Varsayılan TTS motoru olarak ayarlanır ve çevrimdışı çalışır.

Google Metin Okuma Motoru ile birlikte aşağıdaki yerel ayarlar sunulur:

Bengalce
Çince (Mandarin)
Çekçe
Danca
Almanca
Yunanca
İngilizce
İspanyolca
Estonca
Fince
Fransızca
Guceratça
Hintçe
Macarca
Endonezce
İtalyanca
Japonca
Cava Dili
Avustronezce
Avustroasyatik
Kannada Dili
Korece
Malayalam Dili
Norveççe
Felemenkçe
Lehçe
Portekizce
Rusça
Slovakça
Sundanizce
İsveççe
Tamilce
Telugu dili
Tayca
Türkçe
Ukraynaca
Vietnamca

Kamera

Glass Enterprise Edition 2; f/2, 4 diyafram açıklığına, 4:3 sensör en boy oranına ve 83° diyagonal görüş alanına (yatay yönde 71° x 57°) sahip 8 megapiksel, sabit odaklı bir kamerayla donatılmıştır. Standart CameraX veya Camera2 API'yi kullanmanızı öneririz.

Uygulama ayrıntıları için örnek kamera uygulamasını inceleyin.

Kamera düğmesi

Kamera düğmesi, Glass Enterprise Edition 2 cihazının menteşesindeki fiziksel düğmedir. Standart bir klavye işlemi gibi işlenebilir ve KeyEvent#KEYCODE_CAMERA tuş koduyla tanımlanabilir.

OPM1.200313.001 OS güncellemesinden itibaren, Başlatıcı uygulamasından aşağıdaki işlemleri içeren amaçlar gönderilir:

Sensörler

Geliştiriciler, Glass EE2'de uygulama geliştirirken çeşitli sensörlerden yararlanabilir.

Glass'ta aşağıdaki standart Android sensörleri desteklenir:

Glass'ta aşağıdaki Android sensörleri desteklenmez:

Glass sensör koordinat sistemi aşağıdaki resimde gösterilmektedir. Bu, Glass ekranına göre belirlenir. Daha fazla bilgi için Sensör koordinat sistemi başlıklı makaleyi inceleyin.

Glass sensör koordinat sistemi, Glass ekranına göre burada gösterilmektedir.

İvme ölçer, jiroskop ve manyetometre, Glass cihazının optik bölmesinde yer alır. Kullanıcılar, cihazı görüşleriyle hizalamak için bu bölmeyi döndürür. Optik bölmenin açısını doğrudan ölçemezsiniz. Bu nedenle, bu sensörlerden gelen açıları pusula yönü gibi uygulamalarda kullanırken bu durumu göz önünde bulundurun.

Pil ömrünü korumak için sensörleri yalnızca ihtiyacınız olduğunda dinleyin. Sensörleri dinlemeye ne zaman başlayıp ne zaman sonlandıracağınıza karar verirken uygulamanın ihtiyaçlarını ve yaşam döngüsünü göz önünde bulundurun.

Sensör etkinliği geri çağırmaları kullanıcı arayüzü iş parçacığında çalışır. Bu nedenle, etkinlikleri ve dönüşleri mümkün olduğunca hızlı bir şekilde işleyin. İşleme çok uzun sürerse sensör etkinliklerini bir sıraya gönderin ve bunları işlemek için arka plan iş parçacığı kullanın.

50 Hz, baş hareketini izlemek için genellikle yeterli bir örnekleme hızıdır.

Sensörlerin nasıl kullanılacağı hakkında daha fazla bilgi için Android geliştirici kılavuzuna bakın.

Konum hizmetleri

Glass Enterprise Edition 2 cihazında GPS modülü bulunmaz ve kullanıcının konumunu sağlamaz. Ancak yakındaki kablosuz ağların ve Bluetooth cihazlarının listesini göstermek için gerekli olan konum hizmetleri uygulanmıştır.

Uygulamanızda cihaz sahibi ayrıcalıkları varsa ilgili güvenli ayarın değerini programatik olarak değiştirmek için bu ayrıcalıkları kullanabilirsiniz:

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

Üçüncü taraf bir MDM çözümü kullanıyorsanız MDM çözümü bu ayarları sizin için değiştirebilmelidir.