0

任務
使用Android的認證管理器創建一次性登錄功能。使用android創建認證管理器


我目前使用的抽射從形式閱讀電子郵件和密碼,併發送一個請求到服務器

根據需要更改當前進程
爲了能夠創建一個一次性登錄後使用憑證,使用Android身份驗證管理器繼此之後post

問題
1.我的問題在於執行驗證器類的getAuthToken下的fetchTokenFromCredentials方法。以下是代碼片段:

@Override 
    public Bundle getAuthToken(AccountAuthenticatorResponse response, 
      Account account, String authTokenType, Bundle options) 
      throws NetworkErrorException { 

     // We can add rejection of a request for a token type we 
     // don't support here 

     // Get the instance of the AccountManager that's making the 
     // request 
     final AccountManager am = AccountManager.get(mContext); 

     // See if there is already an authentication token stored 
     String authToken = am.peekAuthToken(account, authTokenType); 

     // If we have no token, use the account credentials to fetch 
     // a new one, effectively another logon 
     if (TextUtils.isEmpty(authToken)) { 
      final String password = am.getPassword(account); 
      if (password != null) { 
       authToken = fetchTokenFromCredentials(account.name, password, authTokenType) 
      } 
     } 

     // If we either got a cached token, or fetched a new one, hand 
     // it back to the client that called us. 
     if (!TextUtils.isEmpty(authToken)) { 
      final Bundle result = new Bundle(); 
      result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 
      result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 
      result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 
      return result; 
     } 

     // If we get here, then we don't have a token, and we don't have 
     // a password that will let us get a new one (or we weren't able 
     // to use the password we do have). We need to fetch 
     // information from the user, we do that by creating an Intent 
     // to an Activity child class. 
     final Intent intent = new Intent(mContext, LoginActivity.class); 

     // We want to give the Activity the information we want it to 
     // return to the AccountManager. We'll cover that with the 
     // KEY_ACCOUNT_AUTHENTICATOR_RESPONSE parameter. 
     intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 
       response); 
     // We'll also give it the parameters we've already looked up, or 
     // were given. 
     intent.putExtra(LoginActivity.ARG_IS_ADDING_NEW_ACCOUNT, false); 
     intent.putExtra(LoginActivity.ARG_ACCOUNT_NAME, account.name); 
     intent.putExtra(LoginActivity.ARG_ACCOUNT_TYPE, account.type); 
     intent.putExtra(LoginActivity.ARG_AUTH_TYPE, authTokenType); 

     // Remember that we have to return a Bundle, not an Intent, but 
     // we can tell the caller to run our intent to get its 
     // information with the KEY_INTENT parameter in the returned 
     // Bundle 
     final Bundle bundle = new Bundle(); 
     bundle.putParcelable(AccountManager.KEY_INTENT, intent); 
     return bundle; 
    } 

以前我是用排球,所以我實施fetchTokenfromCredentials是像如下所示。然而,我現在不能使用相同的實現,因爲我需要'返回'一個認證字符串。 Volley異步執行登錄,所以即使我向下面的函數添加返回類型,它也會始終返回null。問:我如何環繞這種情況。我可以使用哪些替代方法?

public void fetchTokenfromCredentials(String name, String password){  
JSONObject loginObject = new JSONObject(); 
      try{ 
       loginObject.put("email", email); 
       loginObject.put("password", password); 
      } catch(JSONException e) { 
       e.printStackTrace(); 
      } 
    // assume predefined url and params 
        JsonObjectRequest loginRequest = new HeaderRequest(Request.Method.POST, url + params, loginObject, 
          new Response.Listener<JSONObject>() { 
           @Override 
           public void onResponse(JSONObject response) { 
            try { 
             JSONObject headers = response.getJSONObject("headers"); 
    // A simple use class that stores the id, username etc. 

            user = new User(response.getInt("id"), response.getString("name"), response.getString("authentication_token"), response.getString("email")); 
// Previous code started a new main activity intent here 

          } catch(JSONException e){ 
           e.printStackTrace(); 
          } 

         } 
        }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        Log.d(TAG,"Failed response"); 
       } 
      }); 
      RequestQueueSingleton.getInstance(this.getApplicationContext()).addToRequestQueue(loginRequest); 
     } 

回答

0

這是我寫的fetchTokensFromCredentials(電子郵件,密碼)函數使用了android HTTP客戶端庫:

URL是使用URI創建建造者

Uri builtUri = Uri.parse(AccountGeneral.LOGIN_QUERY).buildUpon() 
     .build(); 
URL url = null; 
try { 
    url = new URL(builtUri.toString()); 
} catch (MalformedURLException e) { 
    e.printStackTrace(); 
} 

// Stores result of the post response 
     String result = null; 

     // Create a JSON object for the email and password 
     JSONObject loginObject = new JSONObject(); 
     try{ 
      loginObject.put("email", email); 
      loginObject.put("password", password); 
     } catch(JSONException e) { 
      e.printStackTrace(); 
     } 

     // Convert JSON to String 
     String data = loginObject.toString(); 

     // Connection parameters 
     HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
     urlConnection.setDoOutput(true); 
     urlConnection.setRequestProperty("Content-Type", "application/json"); 
     urlConnection.setRequestProperty("Accept", "application/json"); 
     urlConnection.setRequestMethod("POST"); 

     try { 

      //Start POST request - Write 
      OutputStream outputStream = urlConnection.getOutputStream(); 
      BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8")); 
      writer.write(data); 
      writer.close(); 
      outputStream.close(); 

      //Read response 
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8")); 

      String line = null; 
      StringBuilder sb = new StringBuilder(); 

      while ((line = bufferedReader.readLine()) != null) { 
       sb.append(line); 
      } 

      bufferedReader.close(); 
      result = sb.toString(); 

      return result; 

     } finally { 
      urlConnection.disconnect(); 
     } 
0

您可以使用Volley進行同步阻塞請求。該請求將執行網絡請求,同時阻止線程並允許您設置返回類型。

我不熟悉Volley(改裝,FTW!),但我非常肯定它是可行的。

看看這個答案同步請求 - https://stackoverflow.com/a/23808857