אפשר להשתמש באובייקט GoogleApiClient
('לקוח Google API') כדי לגשת לממשקי Google API שכלולים בספריית Google Play Services (כמו כניסה באמצעות חשבון Google, Games ו-Drive). לקוח Google API מספק נקודת כניסה משותפת ל-Google Play Services ומנהל את חיבור הרשת בין המכשיר של המשתמש לכל שירות של Google.
עם זאת, קל יותר להשתמש בממשק GoogleApi
החדש ובתרחישי היישום שלו, והם הדרך המועדפת לגשת לממשקי ה-API של Play Services.
גישה ל-Google APIs
במדריך הזה נסביר איך:
- לנהל את החיבור ל-Google Play Services באופן אוטומטי.
- ביצוע קריאות API סינכרוניות ואסינכרוניות לכל אחד משירותי Google Play.
- לנהל את החיבור ל-Google Play Services באופן ידני במקרים הנדירים שבהם הדבר נדרש. מידע נוסף זמין במאמר חיבורים בניהול ידני.
כדי להתחיל, צריך קודם להתקין את ספריית Google Play Services (מהגרסה 15 ואילך) ל-Android SDK. אם עדיין לא עשיתם זאת, פועלים לפי ההוראות במאמר הגדרת Google Play Services SDK.
הפעלת חיבור שמנוהל באופן אוטומטי
אחרי שמקשרים את הפרויקט לספרייה של Google Play Services, יוצרים מופע של GoogleApiClient
באמצעות ממשקי ה-API של GoogleApiClient.Builder
בשיטה onCreate()
של הפעילות. בכיתה GoogleApiClient.Builder
יש שיטות שמאפשרות לציין את ממשקי Google API שבהם רוצים להשתמש ואת היקפי ההרשאות של OAuth 2.0 הרצויים. דוגמה לקוד שיוצר מכונה של GoogleApiClient
שמתחבר לשירות Google Drive:
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. כדי למנוע שגיאות חיבור, צריך לקרוא ל-method addApiIfAvailable()
ולהעביר את Wearable
API כדי לאפשר ללקוח לטפל בצורה חלקה ב-API החסר. מידע נוסף זמין במאמר גישה ל-Wearable API.
כדי להתחיל חיבור שמנוהל באופן אוטומטי, צריך לציין הטמעה לממשק OnConnectionFailedListener
כדי לקבל שגיאות חיבור שלא ניתן לפתור. כשמכונה מנוהלת באופן אוטומטי של GoogleApiClient
תנסה להתחבר ל-Google APIs, תוצג לה באופן אוטומטי ממשק משתמש כדי לנסות לתקן כשלים בחיבור שניתנים לפתרון (לדוגמה, אם צריך לעדכן את Google Play Services). אם מתרחשת שגיאה שלא ניתן לפתור, תתקבל שיחה למספר onConnectionFailed()
.
אפשר גם לציין הטמעה אופציונלית לממשק ConnectionCallbacks
אם האפליקציה צריכה לדעת מתי החיבור המנוהל באופן אוטומטי נוצר או הושעה. לדוגמה, אם האפליקציה שלכם מבצעת קריאות לכתיבה של נתונים ב-Google APIs, צריך להפעיל אותן רק אחרי הקריאה ל-method onConnected()
.
לפניכם דוגמה לפעילות שמטמיעה את ממשקי הקריאה החוזרת ומוסיפה אותם ללקוח 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 APIs מיד אחרי ה-build של GoogleApiClient
, בלי להמתין להשלמת החיבור.
תקשורת עם שירותי Google
אחרי החיבור, הלקוח יכול לבצע קריאות קריאה וכתיבה באמצעות ממשקי ה-API הספציפיים לשירות שהאפליקציה שלכם מורשית להשתמש בהם, כפי שצוין בממשקי ה-API וההיקפים שהוספתם למכונה של GoogleApiClient
.
הערה: לפני שמבצעים קריאות לשירותי Google ספציפיים, יכול להיות שתצטרכו קודם לרשום את האפליקציה ב-Google Developer Console. להוראות, אפשר לעיין במדריך למתחילים המתאים לממשק ה-API שבו אתם משתמשים, כמו Google Drive או כניסה באמצעות חשבון Google.
כשמבצעים בקשת קריאה או כתיבה באמצעות GoogleApiClient
, לקוח ה-API מחזיר אובייקט PendingResult
שמייצג את הבקשה.
הבדיקה מתבצעת באופן מיידי, לפני שהבקשה מועברת לשירות של Google שאליו האפליקציה שלכם מפעילה קריאה.
לדוגמה, זוהי בקשה לקריאת קובץ מ-Google Drive שמספק אובייקט PendingResult
:
Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)); PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);
אחרי שהאפליקציה תקבל אובייקט PendingResult
, היא תוכל לציין אם הבקשה תטופל כקריאה אסינכרונית או כקריאה סינכרונית.
טיפ: האפליקציה יכולה להוסיף בקשות קריאה לתור גם כשהיא לא מחוברת ל-Google Play Services. לדוגמה, האפליקציה יכולה להפעיל שיטות לקריאת קובץ מ-Google Drive, גם אם המכונה של GoogleApiClient
עדיין לא מחוברת. אחרי יצירת החיבור, מתבצעות בקשות הקריאה שנמצאות בתור. בקשות כתיבה יוצרות שגיאה אם האפליקציה קוראת לשיטות הכתיבה של Google Play Services בזמן ש-Google API Client לא מחובר.
שימוש בקריאות אסינכרוניות
כדי שהבקשה תהיה לא סנכרונית, צריך להפעיל את 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 בשרשור של ממשק המשתמש. האפליקציה יכולה ליצור שרשור חדש באמצעות אובייקט AsyncTask
, ולהשתמש בשרשור הזה כדי לשלוח את הבקשה הסינכרונית.
בדוגמה הבאה מוסבר איך לשלוח בקשה לקבלת קובץ מ-Google Drive כקריאה סינכרונית:
private void loadFile(String filename) { new GetFileTask().execute(filename); } private class GetFileTask extends AsyncTask<String, Void, Void> { 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 // ... } }
גישה ל-Wearable API
Wearable API מספק ערוץ תקשורת לאפליקציות שפועלות במכשירים ניידים ובמכשירים לבישים. ה-API מורכב מקבוצה של אובייקטי נתונים שהמערכת יכולה לשלוח ולסנכרן, וממאזינים שמעדכנים את האפליקציות שלכם על אירועים חשובים באמצעות שכבת נתונים. 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 בנוסף לממשקי Google API אחרים, צריך להפעיל את השיטה addApiIfAvailable()
ולהעביר את Wearable API כדי לבדוק אם הוא זמין. אפשר להשתמש בבדיקת הזמינות הזו כדי לעזור לאפליקציה לטפל בצורה חלקה במקרים שבהם ה-API לא זמין.
בדוגמה הבאה מוסבר איך לגשת ל-Wearable API יחד עם Drive 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 Drive בלי להתחבר ל-Wearable API אם הוא לא זמין. אחרי שמחברים את המכונה של GoogleApiClient
, צריך לוודא ש-Wearable API זמין לפני שמבצעים את הקריאות ל-API:
boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);
התעלמות מכשלים בחיבור ל-API
אם קוראים ל-addApi()
ו-GoogleApiClient
לא מצליח להתחבר לממשק ה-API הזה, כל פעולת החיבור של הלקוח הזה נכשלת ומפעילה את קריאת החזרה (callback) של onConnectionFailed()
.
אפשר להשתמש ב-addApiIfAvailable()
כדי לרשום כישלון בחיבור API ולהתעלם ממנו. אם ממשק API שנוסף באמצעות addApiIfAvailable()
לא מצליח להתחבר בגלל שגיאה שלא ניתן לשחזר (כמו API_UNAVAILABLE
ל-Wear), ממשק ה-API הזה יוסר מ-GoogleApiClient
והלקוח ימשיך להתחבר לממשקי API אחרים. עם זאת, אם חיבור API כלשהו נכשל עם שגיאה שניתן לשחזור (למשל, כוונה לפתרון הסכמה של OAuth), פעולת החיבור של הלקוח נכשלת. כשמשתמשים בחיבור שמנוהל באופן אוטומטי, GoogleApiClient
ינסה לפתור שגיאות כאלה כשהדבר אפשרי. כשמשתמשים בחיבור שמנוהל באופן ידני, המערכת שולחת את הערך ConnectionResult
שמכיל את כוונת הפתרון להודעת החזרה (callback) של 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
- כדי להתאים אישית את הטיפול בשגיאות חיבור ואת הפתרון שלהן
בקטע הזה מפורטות דוגמאות לתרחישי שימוש מתקדמים נוספים.
הפעלת חיבור בניהול ידני
כדי להתחיל חיבור שמנוהל באופן ידני ל-GoogleApiClient
, צריך לציין הטמעה לממשקי ה-callback, ConnectionCallbacks
ו-OnConnectionFailedListener
.
ממשקי ה-API האלה מקבלים קריאות חוזרות בתגובה לשיטה האסינכרונית connect()
כשהחיבור ל-Google Play Services מצליח, נכשל או מושעה.
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 Drive או Google Play Games, סביר להניח שניסיון החיבור הראשון ייכשל והאפליקציה תקבל קריאה ל-onConnectionFailed()
עם השגיאה SIGN_IN_REQUIRED
כי לא צוין חשבון המשתמש.
טיפול בכשלים בחיבור
כשהאפליקציה מקבלת קריאה ל-callback onConnectionFailed()
, צריך לבצע קריאה ל-hasResolution()
באובייקט ConnectionResult
שסופק. אם הפונקציה מחזירה את הערך true, האפליקציה יכולה לבקש מהמשתמש לבצע פעולה מיידית כדי לפתור את השגיאה, על ידי קריאה ל-startResolutionForResult()
באובייקט ConnectionResult
.
השיטה startResolutionForResult()
מתנהגת כמו startActivityForResult()
במצב כזה, ומפעילה פעילות שמתאימה להקשר שעוזרת למשתמש לפתור את השגיאה (למשל, פעילות שעוזרת למשתמש לבחור חשבון).
אם השיטה hasResolution()
מחזירה את הערך false, האפליקציה צריכה להפעיל את השיטה GoogleApiAvailability.getErrorDialog()
ולהעביר את קוד השגיאה לשיטה הזו. הפונקציה מחזירה את הערך Dialog
שמסופק על ידי שירותי Google Play בהתאם לשגיאה. תיבת הדו-שיח עשויה לכלול רק הודעה שמסבירה את השגיאה, או גם פעולה להפעלת פעילות שיכולה לפתור את השגיאה (למשל, אם המשתמש צריך להתקין גרסה חדשה יותר של Google Play Services).
לדוגמה, שיטת הקריאה החוזרת (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()
, הפעילות מקבלת את הקריאה החוזרת (callback) onActivityResult()
עם קוד התוצאה 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
, המשתמש עשוי לסובב את המסך. הפעולה הזו יוצרת מחדש את הפעילות שלכם, וכתוצאה מכך מתבצעת קריאה חוזרת ל-method onStart()
, שמפעילה שוב את connect()
. הפעולה הזו תגרום לקריאה נוספת ל-startResolutionForResult()
, שתציג תיבת דו-שיח נוספת לבחירת חשבון מעל לתיבת הדו-שיח הקיימת.
המאפיין הבוליאני הזה משמש למטרה המיועדת לו רק אם הוא נשמר במופעי הפעילות השונים. בקטע הבא נסביר איך לשמור על מצב טיפול השגיאות באפליקציה למרות פעולות אחרות של משתמשים או אירועים שמתרחשים במכשיר.
שמירה על המצב בזמן פתרון שגיאה
כדי להימנע מהרצת הקוד ב-onConnectionFailed()
בזמן שמתבצע ניסיון קודם לפתרון שגיאה, צריך לשמור משתנה בוליאני שמנטר אם האפליקציה כבר מנסה לפתור שגיאה.
כפי שמוצג בדוגמת הקוד שלמעלה, האפליקציה צריכה להגדיר משתנה בוליאני ל-true
בכל פעם שהיא קוראת ל-startResolutionForResult()
או מציגה את תיבת הדו-שיח מ-GoogleApiAvailability.getErrorDialog()
.
לאחר מכן, כשהאפליקציה מקבלת את הערך RESULT_OK
בקריאה החוזרת (callback) של onActivityResult()
, מגדירים את הערך הבוליאני ל-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 Services.