android - कई गतिविधियों के साथ Google प्लस साइन इन का सही उपयोग कैसे करें?




google-api google-plus google-oauth (4)

मैं इयान बार्बर के उत्तर से सहमत हूं, लेकिन थोड़ा और समझाने के लिए, आपकी Activity दो प्रकारों पर विचार किया जाना चाहिए - Activity एस जो कि साइन इन को हल करता है, और Activity एस जिसमें साइन इन करने की आवश्यकता होती है।

अधिकांश Activity उपयोगकर्ता को प्रमाणित करने के साथ खुद को चिंतित नहीं करती है और आपके ऐप में एक ही तर्क होगा। वे एक GoogleApiClient बनाएंगे, जो डिवाइस पर चल रही Google Play सेवाओं की प्रक्रिया से जुड़ता है और उपयोगकर्ता के कैश्ड साइन-इन को पढ़ता है - यदि onConnected() साइन किया गया है तो वापस onConnected() यदि उपयोगकर्ता साइन इन है और onConnectionFailed() नहीं है तो। आपकी अधिकांश Activity आपके एप्लिकेशन स्थिति को रीसेट करना LoginActivity और उपयोगकर्ता द्वारा साइन इन नहीं किए जाने पर अपनी LoginActivity शुरू कर LoginActivity है। प्रत्येक Activity को GoogleApiClient का अपना उदाहरण बनाए रखना चाहिए क्योंकि यह Google Play द्वारा साझा की गई साझा स्थिति तक पहुँचने के लिए उपयोग की जाने वाली एक हल्की वस्तु है। सेवाओं की प्रक्रिया। उदाहरण के लिए, यह व्यवहार एक साझा BaseActivity क्लास या एक साझा SignInFragment BaseActivity क्लास में समझाया जा सकता है, लेकिन प्रत्येक उदाहरण का अपना GoogleApiClient उदाहरण होना चाहिए।

LoginActivity आपके LoginActivity को अलग तरह से लागू करने की आवश्यकता है। इसे GoogleApiClient भी बनाना चाहिए, लेकिन जब यह onConnected() इंगित करता है कि उपयोगकर्ता द्वारा साइन इन किया गया है, तो उसे उपयोगकर्ता के लिए एक उपयुक्त Activity शुरू करनी चाहिए और finish() करना चाहिए finish() । जब आपका LoginActivity onConnectionFailed() दर्शाता है कि उपयोगकर्ता द्वारा साइन इन नहीं किया गया है, तो आपको startResolutionForResult() साथ समस्याओं को हल करने का प्रयास करना चाहिए।

मल्टी-एक्टिविटी ऐप के प्रवाह के साथ Google+ एपीआई क्लाइंट जीवन चक्र को बांधने का एक अच्छा / अनुशंसित तरीका क्या होगा? गतिविधियों को अपनी कार्यक्षमता को ट्रिगर करने के लिए ऑन-कनेक्ट किए गए एपीआई क्लाइंट विधि पर निर्भर करें, इसका उपयोग केवल एक बार "सक्रियण" चीज के रूप में करें, या शायद कुछ और पूरी तरह से करें?

मैं वर्तमान में यह समझने के लिए संघर्ष कर रहा हूं कि अपने एंड्रॉइड ऐप में Google+ साइन का सही तरीके से उपयोग कैसे किया जाए, जिसमें एक से अधिक गतिविधियां हों।

यह विचार पहले चरण में है कि उपयोगकर्ता को प्रमाणित करने के लिए G + साइन का उपयोग करें और उसके ईमेल प्राप्त करने में सक्षम हों, जैसे सूचनाएं और सामान भेजने के लिए। आखिरकार मैं अन्य Google कार्यक्षमता जैसे मैप्स या अन्य Google Play सेवाएं शुरू करने की योजना बना रहा हूं, इसलिए मुझे लगता है कि इसे पहले से ही लागू करना उपयोगी है।

हालाँकि, मेरा ऐप अपेक्षा के अनुरूप व्यवहार नहीं कर रहा है, और मैंने इस मुद्दे को इस तथ्य तक सीमित कर दिया है कि मैंने अभी तक ऐप चक्र में जी + संकेत को नहीं समझा है जब एक से अधिक गतिविधियां मौजूद हैं।

इस सामान्य तरीके को लागू करने का सही या अनुशंसित तरीका क्या है? वहाँ शायद तरह का एक पैटर्न है जो मुझे सही दिशा में मार्गदर्शन कर सकता है?

उदाहरण के लिए, मुझे एपी क्लाइंट के जीवन चक्र का एक बहुत ही सरल आरेख मिला है , लेकिन यह ऐप के प्रवाह से कैसे संबंधित है?

प्रारंभ में मेरे पास एक लॉगिन गतिविधि है, जहां मैंने हस्ताक्षर को बटन में रखा है। Google के मार्गदर्शक के बाद मैं साइन इन करने में सक्षम हूं और जब ऑनकनेक्ट विधि को कॉल किया जाता है, तो मैं होम एक्टिविटी (डैशबोर्ड या ऐप की मुख्य स्क्रीन जैसी थोड़े) शुरू करता हूं।

यह कुछ हद तक काम करता है। उदाहरण के लिए, प्रत्येक गतिविधि के लिए ऑनस्टार्ट और ऑनटॉप को संभालने का एक अच्छा तरीका क्या होगा? क्या मुझे हर गतिविधि के लिए एपीआई क्लाइंट को हर बार फिर से जोड़ना और फिर से प्रमाणित करना चाहिए? तो शायद यह एक अच्छा विचार यह सब लागू करने के लिए एक BaseActivity है।

एक और मुद्दा यह है कि क्या मुझे उसी एपी क्लाइंट ऑब्जेक्ट का उपयोग करना चाहिए और इसे किसी भी तरह से पास करना चाहिए, या शायद इसे बेस एक्टिविटी क्लास में स्टोर करना चाहिए? या क्या मुझे हर बार एक नया एपीआई क्लाइंट ऑब्जेक्ट बनाना और शुरू करना चाहिए?

कैसे जी + के साथ प्रमाणित करने के लिए केवल लॉगिन गतिविधि का उपयोग करने के बारे में और फिर बस ईमेल प्राप्त करें और इसे स्थानीय डेटाबेस में संग्रहीत करें, और उपयोगकर्ता को "प्रमाणित" या "सक्रिय" या कुछ और के रूप में चिह्नित करें। इससे मुझे हर बार ऐप बंद होने या फिर कनेक्शन निलंबित होने से रोकने में मदद मिलेगी, यहां तक ​​कि कुछ बैटरी बचत के लिए भी।

ऐप वास्तव में जी + पोस्टिंग या उस जैसी किसी अन्य कार्यक्षमता का उपयोग नहीं कर रहा है। आदर्श रूप से इसे अच्छी तरह से ऑफ़लाइन काम करना चाहिए, और केवल प्रारंभिक प्रमाणीकरण या अन्य एक-बार सामान जैसी चीजों के लिए कनेक्शन की आवश्यकता है।

किसी भी सुझाव या सही दिशा में संकेत बहुत सराहना की है।

संपादित करें: मैंने प्रत्येक गाइड और ट्यूटोरियल को पढ़ा है जो मुझे मिल सकता है, जो Google+ का उपयोग करता है, और उनमें से हर एक एकल गतिविधि के दृष्टिकोण से इसे संबोधित करता है। मुझे लगता है कि यह एक सामान्य पर्याप्त समस्या है कि यह एक पैटर्न या कम से कम एक सामान्य दिशानिर्देश से लाभान्वित होगा।


0. टीएल; डीआर

अधीर कोडर के लिए, GitHub पर निम्नलिखित कार्यान्वयन का एक कार्यशील संस्करण पाया जा सकता GitHub

कई अलग-अलग ऐप में कई बार लॉगिन गतिविधि कोड को फिर से लिखने के बाद, एप्लिकेशन वर्ग ऑब्जेक्ट के रूप में आसान (और इतना सुरुचिपूर्ण नहीं) समाधान Google API क्लाइंट बना था। लेकिन, चूंकि कनेक्शन स्थिति UX प्रवाह को प्रभावित करती है, इसलिए मैं इस दृष्टिकोण से कभी खुश नहीं था।

हमारी समस्या को केवल कनेक्शन अवधारणा तक कम करते हुए, हम इस पर विचार कर सकते हैं:

  1. यह Google API क्लाइंट को छुपाता है।
  2. इसके परिमित राज्य हैं।
  3. यह एक (बल्कि) अद्वितीय है।
  4. वर्तमान स्थिति ऐप के व्यवहार को प्रभावित करती है।

1. प्रॉक्सी पैटर्न

चूंकि Connection GoogleApiClient इनकैप्सुलेट करता है, इसलिए यह ConnectionCallbacks और OnConnectionFailedListener

@Override
public void onConnected(Bundle hint) {
    changeState(State.OPENED);
}

@Override
public void onConnectionSuspended(int cause) {
    changeState(State.CLOSED);
    connect();
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    if (currentState.equals(State.CLOSED) && result.hasResolution()) {
        changeState(State.CREATED);
        connectionResult = result;
    } else {
        connect();
    }
}

क्रियाएँ connect , disconnect और revoke के तरीकों के माध्यम से कनेक्शन वर्ग से संवाद कर सकती हैं, लेकिन उनके व्यवहार वर्तमान स्थिति से तय होते हैं। राज्य मशीन द्वारा निम्नलिखित विधियों की आवश्यकता है:

protected void onSignIn() {
    if (!googleApiClient.isConnected() && !googleApiClient.isConnecting()) {
        googleApiClient.connect();
    }
}

protected void onSignOut() {
    if (googleApiClient.isConnected()) {
        Plus.AccountApi.clearDefaultAccount(googleApiClient);
        googleApiClient.disconnect();
        googleApiClient.connect();
        changeState(State.CLOSED);
    }
}

protected void onSignUp() {
    Activity activity = activityWeakReference.get();
    try {
        changeState(State.OPENING);
        connectionResult.startResolutionForResult(activity, REQUEST_CODE);
    } catch (IntentSender.SendIntentException e) {
        changeState(State.CREATED);
        googleApiClient.connect();
    }
}

protected void onRevoke() {
    Plus.AccountApi.clearDefaultAccount(googleApiClient);
    Plus.AccountApi.revokeAccessAndDisconnect(googleApiClient);
    googleApiClient = googleApiClientBuilder.build();
    googleApiClient.connect();
    changeState(State.CLOSED);
}

2. स्टेट पैटर्न

यह एक व्यवहारिक पैटर्न है जो किसी वस्तु को उसके आंतरिक अवस्था में परिवर्तन होने पर उसके व्यवहार को बदलने की अनुमति देता है। GoF डिज़ाइन पैटर्न बुक बताती है कि इस पैटर्न (जो कि हमारा मामला भी है) द्वारा टीसीपी कनेक्शन का प्रतिनिधित्व कैसे किया जा सकता है।

एक राज्य मशीन से एक राज्य एक singleton होना चाहिए, और जावा में ऐसा करना सबसे आसान था कि Enum नाम State :

public enum State {
    CREATED {
        @Override
        void connect(Connection connection) {
            connection.onSignUp();
        }
        @Override
        void disconnect(Connection connection) {
            connection.onSignOut();
        }
    },
    OPENING {},
    OPENED {
        @Override
        void disconnect(Connection connection) {
            connection.onSignOut();
        }
        @Override
        void revoke(Connection connection) {
            connection.onRevoke();
        }
    },
    CLOSED {
        @Override
        void connect(Connection connection) {
            connection.onSignIn();
        }
    };

void connect(Connection connection) {}
void disconnect(Connection connection) {}
void revoke(Connection connection) {}

Connection वर्ग संदर्भ रखता है, अर्थात वर्तमान स्थिति, जो परिभाषित करता है कि Connection तरीके कैसे connect , disconnect और revoke करते हैं, यह व्यवहार करेगा:

public void connect() {
    currentState.connect(this);
}

public void disconnect() {
    currentState.disconnect(this);
}

public void revoke() {
    currentState.revoke(this);
}

private void changeState(State state) {
    currentState = state;
    setChanged();
    notifyObservers(state);
}

3. सिंगलटन पैटर्न

चूंकि इस वर्ग को बार-बार बनाने की आवश्यकता नहीं है, इसलिए हम इसे एकल के रूप में प्रदान करते हैं:

public static Connection getInstance(Activity activity) {
    if (null == sConnection) {
        sConnection = new Connection(activity);
    }

    return sConnection;
}

public void onActivityResult(int result) {
    if (result == Activity.RESULT_OK) {
        changeState(State.CREATED);
    } else {
        changeState(State.CLOSED);
    }
    onSignIn();
}

private Connection(Activity activity) {
    activityWeakReference = new WeakReference<>(activity);

    googleApiClientBuilder = new GoogleApiClient
           .Builder(activity)
           .addConnectionCallbacks(this)
           .addOnConnectionFailedListener(this)
           .addApi(Plus.API, Plus.PlusOptions.builder().build())
           .addScope(new Scope("email"));

    googleApiClient = googleApiClientBuilder.build();
    currentState = State.CLOSED;
}

4. अवलोकनीय प्रतिमान

Connection कक्षा जावा Observable , इसलिए 1 या अधिक गतिविधियां राज्य परिवर्तनों का निरीक्षण कर सकती हैं:

@Override
protected void onCreate(Bundle bundle) {
    connection = Connection.getInstance(this);
    connection.addObserver(this);
}

@Override
protected void onStart() {
    connection.connect();
}

@Override
protected void onDestroy() {
    connection.deleteObserver(this);
    connection.disconnect();
}

@Override
protected void onActivityResult(int request, int result, Intent data) {
    if (Connection.REQUEST_CODE == request) {
        connection.onActivityResult(result);
    }
}

@Override
public void update(Observable observable, Object data) {
    if (observable != connection) {
        return;
    }
    // Your presentation logic goes here...
}

प्रत्येक गतिविधि के लिए पुन: कनेक्ट करना बिल्कुल ठीक है। मोटे तौर पर 3 तरीके हैं जो मैंने इसे लागू करने वाले लोगों के बारे में देखा है:

  1. अधिकांशतः एक आधिपत्य में लागू होते हैं, और दूसरे उसी का विस्तार करते हैं। यह प्रत्येक गतिविधि में कनेक्ट / डिस्कनेक्ट है, लेकिन केवल एक स्थान पर कोड के साथ।
  2. कनेक्ट / डिस्कनेक्ट को एक टुकड़े में लागू करें, और इसमें उन गतिविधियों को शामिल करें जहां ऑर्कुट की जरूरत है। यह तब सहायक होता है जब आपके पास पहले से ही एक ऐसी सक्रियता हो, जिसका आप विस्तार नहीं कर सकते (जैसे कुछ खेल मामले)।
  3. कनेक्ट / डिस्कनेक्ट करने के लिए एक सेवा को लागू करें। यदि आवश्यक हो तो यह एक प्रसारण या इसी तरह की आग लगा सकता है।

ये सभी काम करते हैं, और मैंने उन सभी को वास्तविक दुनिया के ऐप में इस्तेमाल किया है। याद रखने वाली मुख्य बात 99% तर्क को अलग करना है (उपयोगकर्ता या तो साइन इन है या साइन आउट किया गया है, और आपको इसकी जानकारी दी जा रही है) अपेक्षाकृत दुर्लभ "इस वर्तमान समय में साइन-इन" उपयोग के मामले में। इसलिए, उदाहरण के लिए, आप ऑनकनेक्ट हो सकते हैं / ऑनकनेक्शन बहुत अधिक फायरिंग करने में विफल रहा है, लेकिन ज्यादातर आप इसे अनदेखा कर रहे हैं या केवल एप्लिकेशन की स्थिति के अनुसार थोड़ा फ़्लिप कर रहे हैं। केवल एक लॉगिन बटन के साथ एक स्क्रीन पर आपको कनेक्शन परिणाम रिज़ॉल्यूशन और onActivityResult सामान की आवश्यकता होती है। Google Play सेवाओं के कनेक्शन के बारे में सोचें जो उपयोगकर्ता के राज्य के बारे में पूछने के बजाय ज्यादातर उन्हें साइन इन करने के लिए है, और आपको ठीक होना चाहिए।


मेरा दर्शन यह है:

केवल एक गतिविधि बनाएं यदि यह बिल्कुल बिल्कुल जरूरी है। खंड लेनदेन के गुच्छा के लिए उपलब्ध बैकस्टैक के साथ, मैं जितना संभव हो सके अपने ऐप में न्यूनतम गतिविधियां बनाने की कोशिश करता हूं। साथ ही, विभिन्न टुकड़ों के बीच संचार करना गतिविधियों के बीच डेटा भेजने के बजाए बहुत आसान है।

गतिविधि संक्रमण महंगा हैं, है ना? कम से कम मुझे विश्वास है - चूंकि पुरानी गतिविधि को नष्ट / रोका / बंद कर दिया गया है, इसलिए ढेर पर धक्का दिया गया है और फिर नई गतिविधि को बनाया / शुरू / शुरू किया जाना है।

यह सिर्फ मेरा दर्शन है क्योंकि टुकड़े पेश किए गए थे।





android google-api google-plus google-oauth