任务
使用Android的身份验证管理器创建一次性登录功能。
当前流程
我目前正在使用Volley从表单中读取电子邮件和密码并将请求发送到服务器
需要更改
为了能够使用凭据创建一次性登录以使用Android身份验证管理器post
问题
1.我的问题在于在fetchTokenFromCredentials
验证器类下实现getAuthToken
方法。以下是代码段:
@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;
}
以前我使用的是Volley,所以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 :(得分:0)
您可以使用Volley发出同步阻止请求。该请求将执行网络请求,同时阻止线程并允许您设置返回类型。
我对Volley(Retrofit,FTW!)不熟悉,但我很确定它是可行的。
查看同步请求的此答案 - https://stackoverflow.com/a/23808857
答案 1 :(得分:0)
这是我使用android Http Client Library编写fetchTokensFromCredentials(电子邮件,密码)函数的方法:
使用uri构建器
创建了URLUri 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();
}