Android SDK ช่วยให้คุณเข้าถึงข้อมูลที่ป้อนและเซ็นเซอร์ต่างๆ ที่มาพร้อมกับ Glass EE2
หน้านี้แสดงภาพรวมเกี่ยวกับฟีเจอร์ รายละเอียดการใช้งาน และเคล็ดลับที่เป็นประโยชน์
ท่าทางแตะสัมผัส
คุณใช้ Android SDK เพื่อเปิดใช้การเข้าถึงข้อมูลดิบจากทัชแพดของ Glass ได้ ซึ่งทําได้โดยใช้ตัวตรวจจับท่าทางสัมผัสที่จะตรวจจับท่าทางสัมผัสทั่วไปใน Glass โดยอัตโนมัติ เช่น แตะ เลื่อน และเลื่อน
คุณสามารถใช้เครื่องมือตรวจจับท่าทางสัมผัสนี้ในแอปเพื่อดูการแตะ ปัดไปข้างหน้า ปัดกลับ
และปัดลงได้ด้วย ซึ่งคล้ายกับอุปกรณ์ Glass ก่อนหน้านี้
การใช้ท่าทางสัมผัสเหล่านี้เป็นวิธีที่ดีที่สุด ดังนี้
แตะ : ยืนยันหรือป้อน
ปัดไปข้างหน้า ปัดกลับ : เลื่อนดูการ์ดและหน้าจอ
ปัดลง : กลับหรือออก
ดูรายละเอียดการใช้งานได้ในตัวอย่างตัวตรวจจับท่าทางสัมผัส
ตรวจจับท่าทางสัมผัสด้วยตัวตรวจจับท่าทางสัมผัสของ Android
Android GestureDetector
ช่วยให้คุณตรวจหาท่าทางสัมผัสง่ายๆ และซับซ้อน เช่น ท่าทางสัมผัสที่ใช้นิ้วหลายนิ้วหรือการเลื่อน
ตรวจจับท่าทางสัมผัสระดับกิจกรรม
ตรวจจับท่าทางสัมผัสที่ระดับกิจกรรมเฉพาะเมื่อไม่สําคัญกับส่วนใดของ UI ที่สนใจ
ตัวอย่างเช่น หากคุณต้องการเปิดเมนูเมื่อผู้ใช้แตะทัชแพด ไม่ว่าจะโฟกัสมุมมองใด ให้จัดการ MotionEvent
ภายในกิจกรรม
ต่อไปนี้คือตัวอย่างการตรวจจับท่าทางสัมผัสระดับกิจกรรมที่ใช้ GestureDetector
และใช้ GestureDetector.OnGestureListener
เพื่อประมวลผลท่าทางสัมผัสที่รู้จัก ซึ่งจะมีการจัดการและแปลเป็นภาษาต่อไปนี้
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);
}
}
}
}
ตัวอย่างการใช้งาน
หากต้องการใช้การตรวจจับท่าทางสัมผัสระดับกิจกรรม คุณต้องทํางานต่อไปนี้ให้เสร็จ
เพิ่มการประกาศต่อไปนี้ลงในไฟล์ Manifest ภายในการประกาศแอปพลิเคชัน วิธีนี้ช่วยให้
แอปได้รับ MotionEvent
ในกิจกรรม
<application>
<!-- Copy below declaration into your manifest file -->
<meta-data
android:name="com.google.android.glass.TouchEnabledApplication"
android:value="true" />
</application>
ลบล้างเมธอด dispatchTouchEvent(motionEvent)
ของกิจกรรมเพื่อส่งเหตุการณ์การเคลื่อนไหวไปยังเครื่องมือตรวจจับท่าทางสัมผัส onTouchEvent(motionEvent)
นํา GlassGestureDetector.OnGestureListener
มาใช้ในกิจกรรม
ตัวอย่างของเครื่องมือตรวจจับท่าทางสัมผัสระดับกิจกรรมมีดังต่อไปนี้
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);
}
}
หมายเหตุ: โดยค่าเริ่มต้น ระบบจะจัดการท่าทางสัมผัส SWIPE_DOWN
เป็น "Back."
อย่างไรก็ตาม หลังจากเพิ่ม <meta-data android:name="com.google.android.glass.TouchEnabledApplication" android:value="true" />
แล้ว คุณจะเลือกเปลี่ยนการตั้งค่าได้
เพื่อใช้ประโยชน์จากอุปกรณ์ได้อย่างเต็มที่ อย่าลืมเพิ่มประสิทธิภาพท่าทางสัมผัสที่คุณใช้
ตัวอย่างเช่น ViewPager
จะจัดการการปัดไปข้างหน้าและถอยหลังออกจากกล่อง ดังนั้นหากคุณเปลี่ยน SWIPE_FORWARD
และ SWIPE_BACKWARD
ก็จะทํางานไม่ได้ตามที่คาดไว้
Glass Enterprise Edition 2 เป็นอุปกรณ์มาตรฐาน AOSP ที่รองรับแหล่งสัญญาณเสียง พื้นฐาน
แหล่งที่มาของเสียงต่อไปนี้มีการประมวลผลสัญญาณขั้นสูง
การจดจําเสียง
Glass Enterprise Edition 2 สนับสนุนการใช้ภาษาหลักสําหรับการจดจําคําพูด
วิธีนี้รองรับเฉพาะภาษาอังกฤษเท่านั้น
UI การจดจําคําพูดกําลังรอให้ผู้ใช้พูดและส่งคืนข้อความที่ถอดเสียงหลังจากพูดเสร็จ หากต้องการเริ่มต้นกิจกรรม ให้ทําตามขั้นตอนต่อไปนี้
โทรหา startActivityForResult()
ด้วยความตั้งใจของ ACTION_RECOGNIZE_SPEECH
ระบบรองรับฟีเจอร์จุดประสงค์พิเศษต่อไปนี้เมื่อคุณเริ่มกิจกรรม
ลบล้างโค้ดเรียกกลับ onActivityResult()
เพื่อรับข้อความที่ถอดเสียงจากจุดประสงค์พิเศษของ EXTRA_RESULTS
ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้ ระบบจะเรียกใช้โค้ดเรียกกลับนี้เมื่อผู้ใช้พูดจบ
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);
}
หมายเหตุ: ไม่อนุญาตให้ใช้บริการ SpeechRecognizer เชื่อมโยงกับ
โปรดดูรายละเอียดการใช้งานในตัวอย่างแอปการจดจําเสียง
การให้น้ําหนักกับคีย์เวิร์ด
คุณสามารถให้การให้น้ําหนักการจดจําคําพูดใน Glass กับรายการคีย์เวิร์ด การให้น้ําหนักพิเศษจะทําให้
การจดจําคีย์เวิร์ดเพิ่มขึ้น หากต้องการเปิดใช้การให้น้ําหนักกับคีย์เวิร์ด ให้ใช้วิธีต่อไปนี้
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);
คำสั่งเสียง
คําสั่งเสียงช่วยให้ผู้ใช้ดําเนินการจากกิจกรรมได้ คุณสร้างคําสั่งเสียงโดยใช้ API เมนูมาตรฐานของ Android แต่ผู้ใช้เรียกใช้รายการในเมนูด้วยคําสั่งเสียงแทนการแตะได้
หากต้องการเปิดใช้งานคําสั่งเสียงสําหรับกิจกรรมเฉพาะ ให้ทําตามขั้นตอนต่อไปนี้
เรียกใช้ getWindow().requestFeature(FEATURE_VOICE_COMMANDS)
ในกิจกรรมที่ต้องการเพื่อเปิดใช้คําสั่งเสียง เมื่อเปิดใช้ฟีเจอร์นี้ ไอคอนไมโครโฟนจะปรากฏที่มุมล่างซ้ายของหน้าจอเมื่อใดก็ตามที่กิจกรรมนี้โฟกัส
หมายเหตุ: ระบบจะใช้ค่าคงที่ FEATURE_VOICE_COMMANDS
กับฟีเจอร์เดียวกันใน GDK แต่นักพัฒนาซอฟต์แวร์จะต้องกําหนดค่าคงที่ใน EE2 เนื่องจากไม่มี SDK แล้ว
ขอสิทธิ์ RECORD_AUDIO
ในแอป
ลบล้าง onCreatePanelMenu()
และเติมทรัพยากรเมนูให้สูงเกินจริง
ลบล้าง onContextItemSelected()
เพื่อจัดการคําสั่งเสียงที่ตรวจพบ
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);
}
}
}
ตัวอย่างทรัพยากรเมนูที่กิจกรรมก่อนหน้าใช้มีดังนี้
<?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>
อ่านแอปจดโน้ตตัวอย่าง เพื่อดูตัวอย่างทั้งหมด
กําลังโหลดรายการคําสั่งเสียงซ้ํา
คุณสามารถโหลดรายการคําสั่งเสียงซ้ําได้แบบไดนามิก ซึ่งทําได้โดยการแทนที่ทรัพยากร menu
ในเมธอด onCreatePanelMenu()
หรือแก้ไขออบเจ็กต์เมนูในเมธอด onPreparePanel()
หากต้องการใช้การเปลี่ยนแปลง ให้เรียกใช้เมธอด 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();
}
โซลูชัน AppCompatActivity
หากต้องการโหลดรายการคําสั่งเสียงซ้ําในกิจกรรมที่ขยาย AppCompatActivity
ให้ใช้เมธอด sendBroadcast()
ที่มีการทํางานของ Intent ของ reload-voice-commands
Kotlin
sendBroadcast(Intent("reload-voice-commands"))
Java
sendBroadcast(new Intent("reload-voice-commands"));
เปิดหรือปิดใช้คําสั่งเสียงในรันไทม์
คุณเปิดหรือปิดใช้คําสั่งเสียงในรันไทม์ได้ ในการดําเนินการนี้ ให้แสดงผลค่าที่เหมาะสมจากเมธอด onCreatePanelMenu()
ดังนี้
ตั้งค่าเป็น true
เพื่อเปิดใช้
ตั้งค่าเป็น false
เพื่อปิดใช้
โหมดแก้ไขข้อบกพร่อง
หากต้องการเปิดใช้โหมดแก้ไขข้อบกพร่องสําหรับคําสั่งเสียง ให้เรียก getWindow().requestFeature(FEATURE_DEBUG_VOICE_COMMANDS)
ในกิจกรรมที่ต้องการ โหมดแก้ไขข้อบกพร่องจะเปิดใช้ฟีเจอร์ต่อไปนี้
Logcat ประกอบด้วยบันทึกที่มีวลีที่ระบุเพื่อการแก้ไขข้อบกพร่อง
การวางซ้อน UI จะแสดงขึ้นเมื่อตรวจพบคําสั่งที่ไม่รู้จัก ดังนี้
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);
}
.
.
.
}
โปรดดูรายละเอียดการใช้งานในตัวอย่างการโหลดคําสั่งเสียงซ้ํา
การอ่านออกเสียงข้อความ (TTS)
ฟังก์ชันการอ่านออกเสียงข้อความจะแปลงข้อความดิจิทัลเป็นเอาต์พุตสังเคราะห์เสียง ดูข้อมูลเพิ่มเติมได้ที่การอ่านออกเสียงข้อความในเอกสารสําหรับนักพัฒนาซอฟต์แวร์ Android
Glass EE2 มีการติดตั้งเครื่องมือ Google Text-to-Speech
ไว้ ตั้งค่าเป็นเครื่องมือ TTS เริ่มต้นและทํางานแบบออฟไลน์
ภาษาต่อไปนี้มาพร้อมกับเครื่องมืออ่านออกเสียงข้อความของ Google:
เบงกาลี
จีนกลาง
เช็ก
เดนมาร์ก
เยอรมัน
กรีก
อังกฤษ
สเปน
เอสโตเนีย
ฟินแลนด์
ฝรั่งเศส
คุชราต
ฮินดี
ฮังการี
อินโดนีเซีย
อิตาลี
ญี่ปุ่น
ชวา
ออสตราเลเชีย
ออสเตรเลีย
กันนาดา
เกาหลี
มาลายาลัม
นอร์เวย์
ดัตช์
โปแลนด์
โปรตุเกส
รัสเซีย
สโลวัก
สวีเดน
สวีเดน
ทมิฬ
เตลูกู
ไทย
ตุรกี
ยูเครน
เวียดนาม
กล้อง
Glass Enterprise Edition 2 มาพร้อมกล้องแบบโฟกัสคงที่จํานวน 8 เมกะพิกเซลที่มีรูรับแสง f/2.4 อัตราส่วนเซ็นเซอร์ 4:3 และขอบเขตการมองเห็นแนวทแยงมุม 83° (71° x 57° ในแนวนอน)
เราขอแนะนําให้ใช้ API มาตรฐาน X หรือ Camera2
ดูรายละเอียดการใช้งานได้ในตัวอย่างแอปกล้องถ่ายรูป
ปุ่มกล้องคือปุ่มบนบานพับของอุปกรณ์ Glass Enterprise Edition 2
ซึ่งจะจัดการได้เหมือนกับการดําเนินการด้วยแป้นพิมพ์ มาตรฐาน และจะระบุได้ด้วยคีย์คีย์
KeyEvent#KEYCODE_CAMERA
สําหรับการอัปเดตระบบปฏิบัติการ OPM1.200313.001
Intent ที่มีการดําเนินการต่อไปนี้จะส่งจากแอปพลิเคชัน Launcher
เซ็นเซอร์
นักพัฒนาซอฟต์แวร์มีเซ็นเซอร์มากมายที่พร้อมให้บริการในขณะที่พัฒนาแอปพลิเคชันใน Glass EE2
Glass รองรับเซ็นเซอร์ Android มาตรฐานดังต่อไปนี้
Glass ไม่สนับสนุนเซ็นเซอร์ Android ต่อไปนี้
ระบบพิกัดของเซ็นเซอร์ Glass จะแสดงในภาพประกอบต่อไปนี้ สัมพัทธ์กับจอแสดงผล Glass ดูข้อมูลเพิ่มเติมได้ที่ระบบพิกัดเซ็นเซอร์
ตัวตรวจวัดความเร่ง เครื่องวัดการหมุน และเครื่องวัดค่าความเข้มข้นของสนามแม่เหล็กจะอยู่ในพ็อดออปติกของอุปกรณ์ Glass ซึ่งผู้ใช้หมุนเพื่อปรับแนวอุปกรณ์ให้สอดคล้องกับการมองเห็น คุณวัดมุมของพ็อดออปติกโดยตรงไม่ได้ โปรดคํานึงถึงเรื่องนี้เมื่อใช้มุมจากเซ็นเซอร์เหล่านี้ในแอปพลิเคชัน เช่น ส่วนหัวของเข็มทิศ
ฟังเซ็นเซอร์เมื่อคุณต้องการเท่านั้นเพื่อยืดอายุการใช้งานแบตเตอรี่ คํานึงถึง
ความต้องการและวงจรของแอปเมื่อตัดสินใจว่าจะเริ่มต้นและหยุดฟังเซ็นเซอร์เมื่อใด
โค้ดเรียกกลับเหตุการณ์ของเซ็นเซอร์จะทํางานในชุดข้อความ UI ดังนั้นให้ประมวลผลเหตุการณ์และแสดงผลโดยเร็วที่สุด หากการประมวลผลใช้เวลานานเกินไป โปรดพุชเหตุการณ์เซ็นเซอร์ไปยังคิวและใช้ชุดข้อความพื้นหลังเพื่อจัดการ
50 Hz มักเป็นอัตราการสุ่มตัวอย่างที่เพียงพอในการติดตามการเคลื่อนไหวของศีรษะ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้เซ็นเซอร์ได้ที่คู่มือนักพัฒนาซอฟต์แวร์ Android
บริการตำแหน่ง
อุปกรณ์ Glass Enterprise Edition 2 ไม่ได้ติดตั้งโมดูล GPS และไม่ได้ให้ตําแหน่งของผู้ใช้ แต่มีการใช้บริการตําแหน่งซึ่งจําเป็นต่อการแสดงรายชื่อเครือข่าย Wi-Fi และอุปกรณ์บลูทูธใกล้เคียง
หากแอปพลิเคชันมีสิทธิ์ของเจ้าของอุปกรณ์ คุณจะใช้ฟังก์ชันดังกล่าวเพื่อเปลี่ยนค่าของการตั้งค่าความปลอดภัยที่สอดคล้องกันแบบเป็นโปรแกรมได้
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));
}
หากคุณใช้โซลูชัน MDM ของบุคคลที่สาม โซลูชัน MDM ต้องสามารถเปลี่ยนการตั้งค่าเหล่านี้ให้คุณได้