เมื่อต้องการเรียก API รายการใดรายการหนึ่งใน SDK ที่ขับเคลื่อนโดยบริการ Google Play เช่น Google Sign-in หรือ ML Kit คุณจะต้องสร้างอินสแตนซ์ของออบเจ็กต์ไคลเอ็นต์ API ก่อน ออบเจ็กต์เหล่านี้จะจัดการการเชื่อมต่อกับบริการ Google Play โดยอัตโนมัติ เมื่อการเชื่อมต่อพร้อมใช้งาน ออบเจ็กต์ไคลเอ็นต์ API แต่ละรายการจะดำเนินการตามคำขอตามลำดับ ไม่เช่นนั้นออบเจ็กต์ไคลเอ็นต์จะจัดคิวคำขอ การสร้างออบเจ็กต์ไคลเอ็นต์นั้นไม่ยาก การสร้างไคลเอ็นต์ API ใหม่ทุกครั้งที่ต้องการเรียกใช้เมธอด API นั้นไม่มีปัญหาแต่อย่างใด เว้นแต่เอกสารประกอบจะระบุไว้เป็นอย่างอื่น
คู่มือนี้แสดงวิธีเรียก API ไปยัง SDK ที่ขับเคลื่อนโดยบริการ Google Play รวมถึงวิธีเข้าถึงบริการที่ไม่จําเป็นต้องได้รับสิทธิ์และบริการที่จําเป็นต้องได้รับสิทธิ์
เริ่มต้นใช้งาน
ในการเริ่มต้นใช้งาน ให้เพิ่มเครื่องมือและไลบรารีที่จำเป็นในโปรเจ็กต์แอป ตามที่อธิบายไว้ในคู่มือเกี่ยวกับวิธีตั้งค่าบริการ Google Play
การเข้าถึงเมื่อไม่จำเป็นต้องให้สิทธิ์
หากต้องการเข้าถึงบริการที่ไม่จําเป็นต้องให้สิทธิ์ API ให้รับอินสแตนซ์ของออบเจ็กต์ไคลเอ็นต์ของบริการ โดยส่ง Context
ปัจจุบันหรือ Activity
ปัจจุบัน
ก่อนที่จะเรียกใช้ API ระบบจะแจ้งให้ผู้ใช้อัปเกรดบริการ Google Play หากจำเป็น
เช่น หากต้องการทราบตำแหน่งที่ทราบล่าสุดของอุปกรณ์โดยใช้ Fused Location Provider สำหรับ Android ให้เพิ่มตรรกะที่แสดงในข้อมูลโค้ดต่อไปนี้
Kotlin
// Code required for requesting location permissions omitted for brevity. val client = LocationServices.getFusedLocationProviderClient(this) // Get the last known location. In some rare situations, this can be null. client.lastLocation.addOnSuccessListener { location : Location? -> location?.let { // Logic to handle location object. } }
Java
// Code required for requesting location permissions omitted for brevity. FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this); // Get the last known location. In some rare situations, this can be null. client.getLastLocation() .addOnSuccessListener(this, location -> { if (location != null) { // Logic to handle location object. } });
การเข้าถึงเมื่อจำเป็นต้องให้สิทธิ์
หากต้องการเข้าถึงบริการที่ต้องมีการให้สิทธิ์จากผู้ใช้ ให้ทำตามขั้นตอนต่อไปนี้
- ลงชื่อเข้าใช้ผู้ใช้
- ขอสิทธิ์เข้าถึงขอบเขตที่บริการกำหนด
- รับอินสแตนซ์ของออบเจ็กต์ไคลเอ็นต์ของบริการ โดยส่งออบเจ็กต์
GoogleSignInAccount
ของผู้ใช้ไปให้ด้วยนอกเหนือจากออบเจ็กต์Context
หรือActivity
ตัวอย่างต่อไปนี้แสดงการใช้การอ่านจำนวนก้าวของผู้ใช้ในแต่ละวันโดยใช้ Google Fit API หากต้องการดูการใช้งานที่คล้ายกันในบริบทของโปรเจ็กต์แบบสมบูรณ์ ให้ดูกิจกรรมหลักของแอป BasicHistoryApiKotlin บน GitHub
Kotlin
class FitFragment : Fragment() { private val fitnessOptions: FitnessOptions by lazy { FitnessOptions.builder() .addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE) .addDataType(DataType.TYPE_STEP_COUNT_DELTA) .build() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { fitSignIn() } /* * Checks whether the user is signed in. If so, executes the specified * function. If the user is not signed in, initiates the sign-in flow, * specifying the function to execute after the user signs in. */ private fun fitSignIn() { if (oAuthPermissionsApproved()) { readDailySteps() } else { GoogleSignIn.requestPermissions( this, SIGN_IN_REQUEST_CODE, getGoogleAccount(), fitnessOptions ) } } private fun oAuthPermissionsApproved() = GoogleSignIn.hasPermissions(getGoogleAccount(), fitnessOptions) /* * Gets a Google account for use in creating the fitness client. This is * achieved by either using the last signed-in account, or if necessary, * prompting the user to sign in. It's better to use the * getAccountForExtension() method instead of the getLastSignedInAccount() * method because the latter can return null if there has been no sign in * before. */ private fun getGoogleAccount(): GoogleSignInAccount = GoogleSignIn.getAccountForExtension(requireContext(), fitnessOptions) /* * Handles the callback from the OAuth sign in flow, executing the function * after sign-in is complete. */ override fun onActivityResult( requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (resultCode) { RESULT_OK -> { readDailySteps() } else -> { // Handle error. } } } /* * Reads the current daily step total. */ private fun readDailySteps() { Fitness.getHistoryClient(requireContext(), getGoogleAccount()) .readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA) .addOnSuccessListener { dataSet -> val total = when { dataSet.isEmpty -> 0 else -> dataSet.dataPoints.first() .getValue(Field.FIELD_STEPS).asInt() } Log.i(TAG, "Total steps: $total") } .addOnFailureListener { e -> Log.w(TAG, "There was a problem getting the step count.", e) } } companion object { const val SIGN_IN_REQUEST_CODE = 1001 } }
Java
public class FitFragment extends Fragment { private final FitnessOptions fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE) .addDataType(DataType.TYPE_STEP_COUNT_DELTA) .build(); @Override public void onViewCreated( @NotNull View view, @Nullable Bundle savedInstanceState) { fitSignIn(); } /* * Checks whether the user is signed in. If so, executes the specified * function. If the user is not signed in, initiates the sign-in flow, * specifying the function to execute after the user signs in. */ private void fitSignIn() { if (oAuthPermissionsApproved()) { readDailySteps(); } else { GoogleSignIn.requestPermissions(this, SIGN_IN_REQUEST_CODE, getGoogleAccount(), fitnessOptions); } } private boolean oAuthPermissionsApproved() { return GoogleSignIn.hasPermissions(getGoogleAccount(), fitnessOptions); } /* * Gets a Google account for use in creating the fitness client. This is * achieved by either using the last signed-in account, or if necessary, * prompting the user to sign in. It's better to use the * getAccountForExtension() method instead of the getLastSignedInAccount() * method because the latter can return null if there has been no sign in * before. */ private GoogleSignInAccount getGoogleAccount() { return GoogleSignIn.getAccountForExtension( requireContext(), fitnessOptions); } /* * Handles the callback from the OAuth sign in flow, executing the function * after sign-in is complete. */ @Override public void onActivityResult( int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { readDailySteps(); } else { // Handle error. } } /* * Reads the current daily step total. */ private void readDailySteps() { AtomicInteger total = new AtomicInteger(); Fitness.getHistoryClient(requireContext(), getGoogleAccount()) .readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA) .addOnSuccessListener(dataSet -> { if (!dataSet.isEmpty()) total.set(Integer.parseInt(dataSet.getDataPoints() .get(0).getValue(FIELD_STEPS).toString())); Log.i(TAG, "Total steps: $total"); }) .addOnFailureListener(e -> { Log.w(TAG, "There was a problem getting the step count.", e); }); } private static final int SIGN_IN_REQUEST_CODE = 1001; }
ตรวจสอบความพร้อมใช้งานของ API
ก่อนที่จะเปิดใช้ฟีเจอร์ในแอปที่ขึ้นอยู่กับ Google Play Services API ให้ตรวจสอบความพร้อมใช้งานของ API บนอุปกรณ์ โดยโทรไปที่ checkApiAvailability()
ข้อมูลโค้ดต่อไปนี้แสดงวิธีตรวจสอบความพร้อมให้บริการของผู้ให้บริการตำแหน่งแบบรวม
Kotlin
fun getLastLocationIfApiAvailable(context: Context?): Task<Location>? { val client = getFusedLocationProviderClient(context) return GoogleApiAvailability.getInstance() .checkApiAvailability(client) .onSuccessTask { _ -> client.lastLocation } .addOnFailureListener { _ -> Log.d(TAG, "Location unavailable.")} }
Java
public Task<Location> getLastLocationIfApiAvailable(Context context) { FusedLocationProviderClient client = getFusedLocationProviderClient(context); return GoogleApiAvailability.getInstance() .checkApiAvailability(client) .onSuccessTask(unused -> client.getLastLocation()) .addOnFailureListener(e -> Log.d(TAG, "Location unavailable.")); }