การเข้าถึง Google APIs ด้วย GoogleApiClient (เลิกใช้งานแล้ว)

คุณสามารถใช้GoogleApiClient ("ไคลเอ็นต์ Google API") เข้าถึง Google APIs ที่ให้ไว้ในไลบรารีบริการ Google Play (เช่น Google Sign-In, เกม และไดรฟ์) ไคลเอ็นต์ Google API จะมี จุดแรกเข้าทั่วไปไปยังบริการ Google Play และจัดการเครือข่าย การเชื่อมต่อระหว่างอุปกรณ์ของผู้ใช้กับบริการแต่ละอย่างของ Google

อย่างไรก็ตาม อินเทอร์เฟซรุ่นใหม่ของ GoogleApi และการใช้งานง่ายกว่า และเป็นวิธีที่แนะนำในการเข้าถึง API ของบริการ Google Play โปรดดูการเข้าถึง Google API

คู่มือนี้แสดงวิธีทำสิ่งต่อไปนี้

  • จัดการการเชื่อมต่อกับบริการ Google Play โดยอัตโนมัติ
  • เรียกใช้ API แบบพร้อมกันและไม่พร้อมกันไปยังบริการ Google Play บริการใดก็ได้
  • จัดการการเชื่อมต่อกับบริการ Google Play ด้วยตนเองในกรณีที่เกิดขึ้นไม่บ่อยนัก ตามความจำเป็น ดูข้อมูลเพิ่มเติมได้ที่การเชื่อมต่อที่จัดการด้วยตนเอง
รูปที่ 1: ภาพประกอบแสดงวิธีที่ไคลเอ็นต์ Google API สร้าง สำหรับเชื่อมต่อและโทรออกไปยังบริการ Google Play ที่มีให้บริการ เช่น Google Play Games และ Google ไดรฟ์

ในการเริ่มต้นใช้งาน คุณต้องติดตั้งไลบรารีบริการ Google Play (เวอร์ชัน 15 ขึ้นไป) ก่อน สำหรับ Android SDK หากยังไม่ได้ดำเนินการ ให้ทำตามวิธีการใน ตั้งค่า SDK บริการ Google Play

เริ่มการเชื่อมต่อที่มีการจัดการโดยอัตโนมัติ

หลังจากลิงก์โปรเจ็กต์กับไลบรารีบริการ Google Play แล้ว ให้สร้างอินสแตนซ์ GoogleApiClient โดยใช้ GoogleApiClient.Builder API ในกิจกรรม onCreate() GoogleApiClient.Builder ซึ่งมีเมธอดที่ช่วยให้คุณสามารถระบุ Google APIs ที่ต้องการใช้ และ ขอบเขตของ OAuth 2.0 นี่คือตัวอย่างโค้ดที่สร้าง อินสแตนซ์ของ GoogleApiClient ที่เชื่อมต่อกับบริการ Google ไดรฟ์

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
    .enableAutoManage(this /* FragmentActivity */,
                      this /* OnConnectionFailedListener */)
    .addApi(Drive.API)
    .addScope(Drive.SCOPE_FILE)
    .build();

คุณสามารถเพิ่ม API หลายรายการและหลายขอบเขตได้เหมือนกัน GoogleApiClient โดยการเพิ่มการโทรเพิ่มเติมไปที่ addApi() และ addScope()

สำคัญ: หากคุณกำลังเพิ่ม Wearable API ร่วมกับ API อื่นๆ ลงใน GoogleApiClient คุณอาจพบข้อผิดพลาดในการเชื่อมต่อไคลเอ็นต์ในอุปกรณ์ที่ ไม่ได้ติดตั้งแอป Wear OS ไว้ ถึง เพื่อหลีกเลี่ยงข้อผิดพลาดในการเชื่อมต่อ เรียกใช้เมธอด addApiIfAvailable() แล้วส่ง Wearable API เพื่อให้ลูกค้าจัดการกับสิ่งที่ขาดไปได้อย่างราบรื่น API ดูข้อมูลเพิ่มเติมได้ที่เข้าถึง Wearable API

หากต้องการเริ่มการเชื่อมต่อที่มีการจัดการโดยอัตโนมัติ คุณต้องระบุ การใช้งานสำหรับOnConnectionFailedListener เพื่อรับข้อผิดพลาดในการเชื่อมต่อที่แก้ไขไม่ได้ เมื่อคุณจัดการโดยอัตโนมัติ อินสแตนซ์ GoogleApiClient พยายามเชื่อมต่อกับ Google APIs อินสแตนซ์จะ เพื่อพยายามแก้ไขการเชื่อมต่อที่ไม่สำเร็จ (ตัวอย่างเช่น หาก จำเป็นต้องอัปเดตบริการ Google Play) หากเกิดข้อผิดพลาดที่ไม่สามารถ คุณจะได้รับโทรศัพท์ไปยัง onConnectionFailed()

คุณยังระบุการติดตั้งใช้งานที่ไม่บังคับสําหรับอินเทอร์เฟซ ConnectionCallbacks ได้ด้วยหากแอปต้องการทราบเมื่อ การเชื่อมต่อที่มีการจัดการโดยอัตโนมัติถูกสร้างขึ้นหรือถูกระงับ ตัวอย่างเช่น หาก แอปของคุณทำการร้องขอเพื่อเขียนข้อมูลไปยัง Google API ซึ่งควรเรียกใช้ หลังจากที่เรียกใช้เมธอด onConnected() แล้วเท่านั้น

ต่อไปนี้เป็นตัวอย่างกิจกรรมที่ใช้อินเทอร์เฟซ Callback และเพิ่ม ลงในไคลเอ็นต์ Google API

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import gms.drive.*;
import android.support.v4.app.FragmentActivity;

public class MyActivity extends FragmentActivity
        implements OnConnectionFailedListener {
    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a GoogleApiClient instance
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */,
                                  this /* OnConnectionFailedListener */)
                .addApi(Drive.API)
                .addScope(Drive.SCOPE_FILE)
                .build();

        // ...
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // An unresolvable error has occurred and a connection to Google APIs
        // could not be established. Display an error message, or handle
        // the failure silently

        // ...
    }
}

อินสแตนซ์ GoogleApiClient จะเชื่อมต่อโดยอัตโนมัติหลังจากกิจกรรม โทรหา onStart() และยกเลิกการเชื่อมต่อหลังจากโทร onStop() แอปของคุณเริ่มทำให้ อ่านคำขอไปยัง Google API หลังจากการสร้าง GoogleApiClient โดยไม่มี กำลังรอให้การเชื่อมต่อเสร็จสมบูรณ์

สื่อสารกับบริการของ Google

หลังจากเชื่อมต่อแล้ว ไคลเอ็นต์จะอ่านและเขียนการเรียกโดยใช้ API เฉพาะบริการสำหรับ ที่แอปของคุณได้รับอนุญาต ตามที่ระบุโดย API และขอบเขตที่คุณเพิ่ม GoogleApiClient

หมายเหตุ: ก่อนที่จะโทรหาบริการบางอย่างของ Google คุณอาจต้องลงทะเบียน ใน Google Developer Console หากต้องการทราบวิธีการ โปรดดูที่ คู่มือเริ่มต้นใช้งานสำหรับ API ที่คุณใช้งานอยู่ เช่น Google ไดรฟ์ หรือ Google Sign-In

เมื่อคุณส่งคำขออ่านหรือเขียนโดยใช้ GoogleApiClient ไคลเอ็นต์ API จะส่งกลับออบเจ็กต์ PendingResult ที่แสดงถึงคำขอ กรณีนี้จะเกิดขึ้นทันที ก่อนที่ระบบจะส่งคำขอไปยังบริการของ Google ที่แอปของคุณเรียกใช้

ตัวอย่างเช่น นี่คือคำขออ่านไฟล์จาก Google ไดรฟ์ที่ระบุ ออบเจ็กต์ PendingResult:

Query query = new Query.Builder()
        .addFilter(Filters.eq(SearchableField.TITLE, filename));
PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);

หลังจากที่แอปมีออบเจ็กต์ PendingResult แล้ว จากนั้นแอปของคุณสามารถระบุได้ว่าจะให้การจัดการคำขอเป็นการโทรแบบไม่พร้อมกันหรือการโทรพร้อมกัน

เคล็ดลับ: แอปของคุณสามารถจัดคิวคำขออ่านได้ในขณะที่ไม่ได้เชื่อมต่อกับบริการ Google Play สำหรับ เช่น แอปจะเรียกใช้เมธอดเพื่ออ่านไฟล์จาก Google ไดรฟ์ได้ ไม่ว่าอินสแตนซ์ GoogleApiClient จะเชื่อมต่ออยู่หรือไม่ก็ตาม หลังจากสร้างการเชื่อมต่อแล้ว ระบบจะดำเนินการกับคำขออ่านที่จัดคิวไว้ คำขอการเขียนจะทำให้เกิดข้อผิดพลาดหากเรียกใช้แอป บริการ Google Play เขียนเมธอดขณะที่ไคลเอ็นต์ Google API ไม่ได้เชื่อมต่อ

การใช้การโทรแบบไม่พร้อมกัน

หากต้องการทำให้คำขอไม่พร้อมกัน ให้เรียกใช้ setResultCallback() ใน PendingResult และระบุ การนำ อินเทอร์เฟซ ResultCallback สำหรับ ตัวอย่างเช่น ต่อไปนี้คือคำขอที่ดำเนินการแบบไม่พร้อมกัน

private void loadFile(String filename) {
    // Create a query for a specific filename in Drive.
    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, filename))
            .build();
    // Invoke the query asynchronously with a callback method
    Drive.DriveApi.query(mGoogleApiClient, query)
            .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
        @Override
        public void onResult(DriveApi.MetadataBufferResult result) {
            // Success! Handle the query result.
            // ...
        }
    });
}

เมื่อแอปได้รับออบเจ็กต์ Result ใน Callback ของ onResult() มีการส่งเป็นอินสแตนซ์ของคลาสย่อยที่เหมาะสม ตามที่ระบุโดย API ที่คุณใช้ เช่น DriveApi.MetadataBufferResult

การใช้การโทรพร้อมกัน

ถ้าคุณต้องการให้โค้ดของคุณทำงานตามลำดับที่กำหนดไว้อย่างเคร่งครัด อาจเป็นเพราะผลลัพธ์ของ ต้องมีการเรียกเป็นอาร์กิวเมนต์ของอีกรายการหนึ่ง คุณสามารถทำให้คำขอของคุณพร้อมกันได้โดยการเรียกใช้ await() ใน PendingResult การดำเนินการนี้จะบล็อกชุดข้อความ และแสดงผลออบเจ็กต์ Result เมื่อ คำขอเสร็จสมบูรณ์ ออบเจ็กต์นี้นำส่งเป็นอินสแตนซ์ของคลาสย่อยที่เหมาะสมตามที่ระบุโดย เช่น API ที่คุณใช้งานอยู่ DriveApi.MetadataBufferResult

เนื่องจากโทรหา await() บล็อกเทรดจนกว่าผลลัพธ์จะมาถึง แอปของคุณไม่ควรส่งคำขอแบบพร้อมกันไปยัง Google APIs ใน ชุดข้อความ UI แอปของคุณสามารถสร้างชุดข้อความใหม่โดยใช้ออบเจ็กต์ AsyncTask และใช้ชุดข้อความนั้นเพื่อสร้างคำขอแบบซิงโครนัส

ตัวอย่างต่อไปนี้แสดงวิธีส่งคำขอไฟล์ไปยัง Google ไดรฟ์เป็นการเรียกพร้อมกัน

private void loadFile(String filename) {
    new GetFileTask().execute(filename);
}

private class GetFileTask extends AsyncTask {
    protected void doInBackground(String filename) {
        Query query = new Query.Builder()
                .addFilter(Filters.eq(SearchableField.TITLE, filename))
                .build();
        // Invoke the query synchronously
        DriveApi.MetadataBufferResult result =
                Drive.DriveApi.query(mGoogleApiClient, query).await();

        // Continue doing other stuff synchronously
        // ...
    }
}

เข้าถึง API ที่สวมใส่ได้

Wearable API มีช่องทางการสื่อสารสำหรับแอปที่ทำงานในอุปกรณ์พกพาและอุปกรณ์ที่สวมใส่ได้ API ประกอบด้วยชุดออบเจ็กต์ข้อมูลที่ระบบส่งและซิงค์ข้อมูลได้ และ Listener ที่แจ้งแอปของคุณเกี่ยวกับเหตุการณ์สำคัญโดยใช้ชั้นข้อมูล Wearable API พร้อมใช้งานในอุปกรณ์ที่ใช้ Android 4.3 (API ระดับ 18) ขึ้นไปเมื่อ เชื่อมต่ออุปกรณ์ที่สวมใส่ได้และมีแอปที่ใช้ร่วมกันกับ Wear OS ติดตั้งอยู่ในอุปกรณ์

การใช้ Wearable API แบบสแตนด์อโลน

หากแอปของคุณใช้ Wearable API ซึ่งไม่ใช่ API อื่นๆ ของ Google ให้เพิ่ม API นี้โดย ที่เรียกใช้เมธอด addApi() ตัวอย่างต่อไปนี้จะแสดงวิธีเพิ่มส่วน Wearable API ไปยังอินสแตนซ์ GoogleApiClient

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
    .enableAutoManage(this /* FragmentActivity */,
                      this /* OnConnectionFailedListener */)
    .addApi(Wearable.API)
    .build();

ในกรณีที่ Wearable API ไม่พร้อมใช้งาน จะส่งคำขอเชื่อมต่อ รวมถึง Wearable API ล้มเหลวโดยมีแอตทริบิวต์ API_UNAVAILABLE รหัสข้อผิดพลาด

ตัวอย่างต่อไปนี้แสดงวิธีตรวจสอบว่า Wearable API พร้อมใช้งานหรือไม่

// Connection failed listener method for a client that only
// requests access to the Wearable API
@Override
public void onConnectionFailed(ConnectionResult result) {
    if (result.getErrorCode() == ConnectionResult.API_UNAVAILABLE) {
        // The Wearable API is unavailable
    }
    // ...
}

การใช้ Wearable API กับ Google API อื่นๆ

หากแอปของคุณใช้ Wearable API นอกเหนือจาก API อื่นๆ ของ Google ให้เรียกใช้เมธอด addApiIfAvailable() และส่งใน Wearable API เพื่อตรวจสอบว่าใช้งานได้หรือไม่ คุณใช้การตรวจสอบนี้เพื่อช่วยให้แอปจัดการกับกรณีที่ API ไม่พร้อมใช้งานได้อย่างราบรื่น

ตัวอย่างต่อไปนี้แสดงวิธีเข้าถึง Wearable API รวมถึง API ไดรฟ์:

// Create a GoogleApiClient instance
mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this /* FragmentActivity */,
                          this /* OnConnectionFailedListener */)
        .addApi(Drive.API)
        .addApiIfAvailable(Wearable.API)
        .addScope(Drive.SCOPE_FILE)
        .build();

ในตัวอย่างด้านบน GoogleApiClient สามารถเชื่อมต่อกับ Google ไดรฟ์โดยไม่เชื่อมต่อกับ Wearable API หากไม่พร้อมใช้งาน หลัง คุณเชื่อมต่อ GoogleApiClient อินสแตนซ์ ให้ตรวจสอบว่า Wearable API พร้อมใช้งานก่อนเรียก API โดยทำดังนี้

boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);

การละเว้นความล้มเหลวในการเชื่อมต่อ API

หากคุณโทรหา addApi() และ GoogleApiClient ดำเนินการต่อไปนี้ไม่ได้ เชื่อมต่อกับ API นั้นได้สำเร็จ การดำเนินการเชื่อมต่อทั้งหมดสำหรับไคลเอ็นต์นั้นล้มเหลว และ เรียกใช้ Callback onConnectionFailed()

คุณสามารถลงทะเบียนความล้มเหลวในการเชื่อมต่อ API ที่จะถูกละเว้นได้โดยใช้ addApiIfAvailable() ในกรณีที่เพิ่ม API ด้วย addApiIfAvailable() เชื่อมต่อไม่สำเร็จเนื่องจากเกิดข้อผิดพลาดที่กู้คืนไม่ได้ (เช่น API_UNAVAILABLE สำหรับ Wear) ที่ API ถูกตัดออกจาก GoogleApiClient ของคุณ และไคลเอ็นต์จะไปที่ เชื่อมต่อกับ API อื่นๆ อย่างไรก็ตาม หากการเชื่อมต่อ API ล้มเหลวโดยมีข้อผิดพลาดที่กู้คืนได้ (เช่น ความตั้งใจในการแก้ปัญหาความยินยอม OAuth) ดำเนินการเชื่อมต่อไคลเอ็นต์ไม่สำเร็จ วันและเวลา ใช้การเชื่อมต่อที่มีการจัดการโดยอัตโนมัติ GoogleApiClient จะพยายาม เพื่อแก้ไขข้อผิดพลาดดังกล่าวเมื่อเป็นไปได้ เมื่อใช้การเชื่อมต่อที่มีการจัดการด้วยตนเอง ConnectionResult ที่มีความตั้งใจในการแก้ปัญหา ที่ส่งไปยังหมายเลขติดต่อกลับของ onConnectionFailed() API ระบบจะเพิกเฉยต่อความล้มเหลวในการเชื่อมต่อเฉพาะในกรณีที่ไม่มีวิธีการแก้ไขสำหรับความล้มเหลวดังกล่าว และเพิ่ม API แล้ว ด้วย addApiIfAvailable() ดูวิธีใช้การเชื่อมต่อด้วยตนเองไม่สำเร็จ โปรดดูที่ส่วนจัดการความล้มเหลวในการเชื่อมต่อ

เนื่องจาก API ที่เพิ่มด้วย addApiIfAvailable() อาจไม่แสดงอยู่ในการเชื่อมต่อ GoogleApiClient คุณควรป้องกันการเรียกใช้ API เหล่านี้โดยเพิ่มการตรวจสอบ ด้วย hasConnectedApi() เพื่อหาว่าเพราะเหตุใด API บางรายการล้มเหลวในการเชื่อมต่อเมื่อการดำเนินการเชื่อมต่อทั้งหมดสำหรับไคลเอ็นต์สำเร็จ โทร getConnectionResult() และรับรหัสข้อผิดพลาดจาก ออบเจ็กต์ ConnectionResult ในกรณีที่ไคลเอ็นต์ของคุณเรียกใช้ API เมื่อไม่ได้ใช้ แต่การติดต่อนั้นล้มเหลวโดยมี API_NOT_AVAILABLE รหัสสถานะ

หาก API ที่คุณจะเพิ่มผ่าน addApiIfAvailable() จำเป็นต้องใช้หรือ ขอบเขตเพิ่มเติม ให้เพิ่มขอบเขตเหล่านั้นเป็นพารามิเตอร์ใน แทนการใช้เมธอด addApiIfAvailable() addScope() ระบบอาจไม่ขอขอบเขตที่เพิ่มโดยใช้แนวทางนี้หาก API เชื่อมต่อไม่สำเร็จก่อนที่จะขอความยินยอม OAuth ในขณะที่เพิ่มขอบเขตด้วย มีการขอ addScope() เสมอ

การเชื่อมต่อที่จัดการด้วยตนเอง

เนื้อหาส่วนใหญ่ของคู่มือนี้จะแสดงวิธีใช้ enableAutoManage เพื่อเริ่มต้น ให้กับการเชื่อมต่อที่มีการจัดการโดยอัตโนมัติ พร้อมกับแก้ไขข้อผิดพลาดโดยอัตโนมัติ ในอีกเกือบ ทั้งหมด วิธีนี้เป็นวิธีที่ดีที่สุดและง่ายที่สุดในการเชื่อมต่อกับ Google APIs จาก แอปสำหรับ Android แต่ก็มีบางกรณีที่คุณอาจต้องใช้ การเชื่อมต่อที่มีการจัดการด้วยตนเองกับ Google APIs ในแอปของคุณ

  • เพื่อเข้าถึง Google API นอกเหนือจากกิจกรรม หรือยังคงควบคุม API ได้ การเชื่อมต่อ
  • เพื่อปรับแต่งการจัดการและแก้ปัญหาข้อผิดพลาดในการเชื่อมต่อ

ส่วนนี้จะแสดงตัวอย่าง Use Case เหล่านี้และขั้นสูงอื่นๆ

เริ่มการเชื่อมต่อที่มีการจัดการด้วยตนเอง

หากต้องการเริ่มการเชื่อมต่อที่มีการจัดการด้วยตนเองกับ GoogleApiClient คุณต้องดำเนินการต่อไปนี้ ระบุการใช้งานสำหรับอินเทอร์เฟซ Callback ConnectionCallbacks และ OnConnectionFailedListener อินเทอร์เฟซเหล่านี้จะได้รับ Callback เพื่อตอบสนองต่อการอะซิงโครนัส connect() เมื่อเมธอด การเชื่อมต่อกับบริการ Google Play สำเร็จ ไม่สำเร็จ หรือถูกระงับ

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Drive.API)
            .addScope(Drive.SCOPE_FILE)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build()

เมื่อจัดการการเชื่อมต่อด้วยตนเอง คุณจะต้องเรียกใช้ connect() และ disconnect() ณ จุดที่เหมาะสมในวงจรของแอป ในกิจกรรม บริบทที่แนวทางปฏิบัติแนะนำคือการเรียกใช้ connect() ใน onStart() ของกิจกรรม และ disconnect() ในเมธอด onStop() ของกิจกรรม connect() และ เมธอด disconnect() จะถูกเรียกโดยอัตโนมัติเมื่อใช้การเชื่อมต่อที่มีการจัดการโดยอัตโนมัติ

หากคุณใช้ GoogleApiClient เพื่อเชื่อมต่อกับ API ที่ต้องใช้ เช่น Google ไดรฟ์ หรือ Google Play Games การเชื่อมต่อครั้งแรกของคุณจะไม่สำเร็จและแอปจะได้รับสายเรียกเข้า ถึง onConnectionFailed() ด้วย SIGN_IN_REQUIRED เนื่องจากไม่ได้ระบุบัญชีผู้ใช้

จัดการความล้มเหลวในการเชื่อมต่อ

เมื่อแอปรับสายไปที่onConnectionFailed() Callback คุณควรโทรหา hasResolution() ใน ConnectionResult ที่ระบุไว้ ออบเจ็กต์ หากผลลัพธ์แสดงเป็น "จริง" แอปสามารถขอให้ผู้ใช้ดำเนินการแก้ไขข้อผิดพลาดในทันทีโดย กำลังโทรหา startResolutionForResult() ในออบเจ็กต์ ConnectionResult เมธอด startResolutionForResult() จะทำงานเหมือนกับ startActivityForResult() ในสถานการณ์นี้ และเปิดกิจกรรมที่เหมาะสมกับบริบทที่ช่วยให้ผู้ใช้แก้ไขข้อผิดพลาดได้ (เช่น กิจกรรมที่ช่วยให้ผู้ใช้ดำเนินการ เลือกบัญชี)

หากเป็น hasResolution() แสดงค่าเท็จ แอปของคุณควรเรียกใช้ GoogleApiAvailability.getErrorDialog() การส่งรหัสข้อผิดพลาดไปยังเมธอดนี้ ซึ่งจะแสดง Dialog ให้บริการโดย Google Play บริการที่เหมาะสมสำหรับข้อผิดพลาด กล่องโต้ตอบอาจมีเพียงข้อความอธิบาย หรืออาจระบุการดำเนินการเพื่อเปิดกิจกรรมที่แก้ไขข้อผิดพลาดได้ (เช่น เมื่อผู้ใช้ต้องติดตั้งบริการ Google Play เวอร์ชันใหม่)

ตัวอย่างเช่น ตอนนี้เมธอด Callback onConnectionFailed() ควรมีลักษณะดังนี้

public class MyActivity extends Activity
        implements ConnectionCallbacks, OnConnectionFailedListener {

    // Request code to use when launching the resolution activity
    private static final int REQUEST_RESOLVE_ERROR = 1001;
    // Unique tag for the error dialog fragment
    private static final String DIALOG_ERROR = "dialog_error";
    // Bool to track whether the app is already resolving an error
    private boolean mResolvingError = false;

    // ...

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        if (mResolvingError) {
            // Already attempting to resolve an error.
            return;
        } else if (result.hasResolution()) {
            try {
                mResolvingError = true;
                result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
            } catch (SendIntentException e) {
                // There was an error with the resolution intent. Try again.
                mGoogleApiClient.connect();
            }
        } else {
            // Show dialog using GoogleApiAvailability.getErrorDialog()
            showErrorDialog(result.getErrorCode());
            mResolvingError = true;
        }
    }

    // The rest of this code is all about building the error dialog

    /* Creates a dialog for an error message */
    private void showErrorDialog(int errorCode) {
        // Create a fragment for the error dialog
        ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
        // Pass the error that should be displayed
        Bundle args = new Bundle();
        args.putInt(DIALOG_ERROR, errorCode);
        dialogFragment.setArguments(args);
        dialogFragment.show(getSupportFragmentManager(), "errordialog");
    }

    /* Called from ErrorDialogFragment when the dialog is dismissed. */
    public void onDialogDismissed() {
        mResolvingError = false;
    }

    /* A fragment to display an error dialog */
    public static class ErrorDialogFragment extends DialogFragment {
        public ErrorDialogFragment() { }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Get the error code and retrieve the appropriate dialog
            int errorCode = this.getArguments().getInt(DIALOG_ERROR);
            return GoogleApiAvailability.getInstance().getErrorDialog(
                    this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR);
        }

        @Override
        public void onDismiss(DialogInterface dialog) {
            ((MyActivity) getActivity()).onDialogDismissed();
        }
    }
}

หลังจากที่ผู้ใช้ดำเนินการเสร็จสิ้นตามกล่องโต้ตอบที่ระบุโดย startResolutionForResult() หรือปิดข้อความที่ระบุโดย GoogleApiAvailability.getErrorDialog() กิจกรรมของคุณจะได้รับ onActivityResult() Callback พร้อม RESULT_OK รหัสผลลัพธ์ จากนั้นแอปของคุณจะเรียก connect() อีกครั้ง เช่น

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_RESOLVE_ERROR) {
        mResolvingError = false;
        if (resultCode == RESULT_OK) {
            // Make sure the app is not already connected or attempting to connect
            if (!mGoogleApiClient.isConnecting() &&
                    !mGoogleApiClient.isConnected()) {
                mGoogleApiClient.connect();
            }
        }
    }
}

ในโค้ดข้างต้น คุณอาจสังเกตเห็นบูลีน mResolvingError ซึ่งจะติดตามผลของ สถานะแอปขณะที่ผู้ใช้กำลังแก้ไขข้อผิดพลาดเพื่อหลีกเลี่ยงการพยายามแก้ไขสิ่งเดิมซ้ำๆ ตัวอย่างเช่น ในขณะที่กล่องโต้ตอบเครื่องมือเลือกบัญชีแสดงขึ้นเพื่อช่วยผู้ใช้ในการแก้ไข SIGN_IN_REQUIRED ผู้ใช้อาจหมุนหน้าจอ วิธีนี้จะสร้างกิจกรรมของคุณอีกครั้งและทําให้ onStart() เป็นเมธอด อีกครั้ง ซึ่งจากนั้นจะเรียก connect() อีกครั้ง ช่วงเวลานี้ ทำให้การเรียกอีก startResolutionForResult() ซึ่งจะสร้างกล่องโต้ตอบเครื่องมือเลือกบัญชีขึ้นหน้ากล่องโต้ตอบที่มีอยู่

บูลีนนี้ตามวัตถุประสงค์ที่กําหนดไว้เฉพาะในกรณีที่ยังคงอยู่ในอินสแตนซ์กิจกรรมเท่านั้น ส่วนถัดไปอธิบายวิธีรักษาสถานะการจัดการข้อผิดพลาดของแอป แม้ว่าผู้ใช้จะมีการดำเนินการอื่นๆ ก็ตาม หรือเหตุการณ์ที่เกิดขึ้นในอุปกรณ์

คงสถานะไว้ขณะแก้ไขข้อผิดพลาด

เพื่อหลีกเลี่ยงการเรียกใช้โค้ดใน onConnectionFailed() ขณะที่การพยายามแก้ไขข้อผิดพลาดครั้งก่อนอยู่ระหว่างดำเนินการ คุณจะต้องเก็บบูลีนไว้ ติดตามว่าแอปของคุณพยายามแก้ไขข้อผิดพลาดแล้วหรือไม่

ดังที่แสดงในตัวอย่างโค้ดด้านบน แอปของคุณควรตั้งค่าบูลีนเป็น true ทุกครั้งที่เรียกใช้ startResolutionForResult() หรือแสดงกล่องโต้ตอบจาก GoogleApiAvailability.getErrorDialog() จากนั้นเมื่อแอปได้รับ RESULT_OK ในช่วง onActivityResult() Callback ตั้งค่าบูลีนเป็น false

เพื่อติดตามบูลีนเมื่อรีสตาร์ทกิจกรรม (เช่น เมื่อผู้ใช้หมุนหน้าจอ) บันทึกบูลีนในข้อมูลอินสแตนซ์ที่บันทึกไว้ของกิจกรรมโดยใช้ onSaveInstanceState():

private static final String STATE_RESOLVING_ERROR = "resolving_error";

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}

จากนั้นกู้คืนสถานะที่บันทึกไว้ในระหว่าง onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...
    mResolvingError = savedInstanceState != null
            && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
}

ตอนนี้คุณก็พร้อมที่จะเรียกใช้แอปอย่างปลอดภัยและเชื่อมต่อกับบริการ Google Play ด้วยตนเองแล้ว