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