2012-07-11 14 views
16

का उपयोग करते समय दो बार लॉग इन करें मैं डीबी सिंक को संभालने के लिए SyncAdapter का उपयोग कर एक नया एंड्रॉइड ऐप बना रहा हूं। मेरे पास सब कुछ है और ऐप ठीक काम कर रहा है लेकिन मैंने देखा कि मैं दो बार लॉग इन हूं।SyncAdapters

पहला लॉगिन तब होता है जब AuthenticatorActivity कक्षा (यह AccountAuthenticatorActivity तक फैली हुई है) उपयोगकर्ता और पासवर्ड को मान्य करती है।

उपयोगकर्ता और पासवर्ड सही हैं, तो AuthenticatorActivity तो करता है:

  • तो account मौजूद नहीं था यह mAccountManager.addAccountExplicitly()
  • authTokenintent.putExtra(AccountManager.KEY_AUTHTOKEN, authToken);

इस का उपयोग करते हुए सहेजा जाता है का उपयोग कर बनाता है मूल रूप से एंड्रॉइड नमूने से कॉपी/पेस्ट किया गया था, इसलिए मुझे लगता है कि यह ठीक है।

मुद्दा यह है कि जब SyncAdapter की शुरूआत और उपयोग करता

authtoken = mAccountManager.blockingGetAuthToken(account, 
      AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, true); 

getAuthToken() विधि Authenticator वर्ग जो AbstractAccountAuthenticator फैली अंदर कहा जाता है। और इस विधि के अंदर मैं एक बार फिर लॉगिन एंडपॉइंट मार रहा हूं।

उस बिंदु के बाद से लॉगिन endpoint फिर से हिट नहीं हो जाने तक authToken समाप्त हो रहा है।

यह कुछ मुझे बहुत परेशान करती है, लेकिन मैं अगर वहाँ एक तरह से दो बार लॉगिन कर से बचने के लिए है जानना चाहते हैं कि नहीं है।

+0

बंडल में वापस टोकन पास करने के बजाय 'AccountManager.setAuthToken()' का उपयोग करने के बारे में क्या? – alexanderblom

+0

@alexanderblom: मैंने भी कोशिश की। कोई फर्क नहीं। – Macarse

+1

मुझे लगता है कि दो लॉग इन के पीछे कारण यह सुनिश्चित करना था कि ऑथ टोकन अद्यतित हैं, लेकिन मुझे स्रोत का समर्थन करने के लिए मुझे स्रोत नहीं मिला। मुझे इसे कहीं और पढ़ना याद है जब मैंने सी 2 डीएम उदाहरण का पालन करने की कोशिश की, जब यह पहली बार Google I/O में पहली बार बाहर आया ... – Yenchi

उत्तर

14

आप देखा है के रूप में, हालांकि SampleSyncAdapter में Authenticator.java कहते

दिलचस्प बात यह है कि इस वर्ग को दर्शाता है प्रमाणीकरण की प्रक्रिया के हिस्से के रूप में authTokens का उपयोग है। ... अगर हमारे पास खाते में संग्रहीत ऑथोकन पहले से है, तो हम उस ऑथोकन को वापस कर देते हैं। अगर हम नहीं करते हैं, लेकिन हमारे पास उपयोगकर्ता नाम और पासवर्ड है, तो हम एक ऑथोकन लाने के लिए नमूना सेवा से बात करने का प्रयास करेंगे।

कि एक झूठ है। Authenticator.getAuthToken किसी भी कैश की जांच के लिए नहीं है, यह सिर्फ टोकन प्राप्त करने के लिए नेटवर्क को हिट करता है। कि अपनी परियोजना के बाकी वरना धार्मिक AccountManager.invalidateAuthToken उपयोग करने के लिए जब कॉल असफल की जरूरत है आप में नाकाम रहने के कॉल की एक अनंत लूप के साथ हवा जाएगा

Authenticator.java: 
@Override 
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, 
     String authTokenType, Bundle loginOptions) throws NetworkErrorException { 

    // check that authToken type supported 
    ... 

    // Check if we already have a cached token to return 
    final AccountManager am = AccountManager.get(mContext); 
    String cachedAuthToken = am.peekAuthToken(account, authTokenType); 
    if (cachedAuthToken != null) { 
     final Bundle result = new Bundle(); 
     result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 
     result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE); 
     result.putString(AccountManager.KEY_AUTHTOKEN, cachedAuthToken); 
     return result; 
    } 

    // Get new authToken from server 
    ... 

    // If all else fails, prompt the user for credentials 
    ... 
} 

नोट:

समाधान लापता जांच में जोड़ने के लिए है , एक नया ऑथ टोकन प्राप्त करने का प्रयास कर रहा है, और फिर उसी कैश किए गए ऑथ टोकन को वापस करने पर फिर से विफल हो रहा है।

+2

यदि आपको एक पूर्ण कामकाजी उदाहरण की आवश्यकता है, तो मैंने अपने ब्लॉग पोस्ट के लिए मेरे नमूना सिंक एडाप्टर पर एक ही तकनीक का उपयोग किया उस विषय पर। https://github.com/Udinic/SyncAdapter सिंक एडाप्टर के बारे में यहाँ ब्लॉग पोस्ट:: http://udinic.wordpress.com/2013/07/24/ आप यहाँ नमूना एप्लिकेशन कोड देख सकते हैं लिखिए-अपना-एंड-एंड्रॉइड-सिंक-एडाप्टर/ विशिष्ट रूप से प्रमाणीकरणकर्ताओं के बारे में, इस समस्या को समझाते हुए, आप यहां पढ़ सकते हैं: http://udinic.wordpress.com/2013/04/24/write-your-own- एंड्रॉइड-प्रामाणिक/ – Udinic

+0

कक्षा में जो खाता प्रमाणीकरण सक्रियता बढ़ाता है, मैं am.setAuthToken (स्ट्रिंग) और am.setPassword (स्ट्रिंग) को कॉल करता हूं। कक्षा में जो सार तत्व अकाउंटिकेटर को विस्तारित करता है, मैं am.peekAuthToken (खाता, authTokenType) को कॉल करता हूं; यह पहली बार शून्य वापस आता है। इसके बाद खाते से उपयोगकर्ता नाम और खाता प्रबंधक (am.getPassword (खाता)) में सहेजे गए पासवर्ड का उपयोग करने में लॉग इन होता है; और उसके बाद लेखांकनकर्ता को GetAuthToken द्वारा लौटाए गए बंडल के माध्यम से खाता प्रबंधक में सहेजा जाता है। किसी को पता है क्यों am.setPassword() सफलतापूर्वक पासवर्ड सेट करता है लेकिन am.setAuthToken (स्ट्रिंग) नहीं करता है? – Ethan