2013-06-16 13:28:41 +02:00

190 lines
6.3 KiB
Java

package com.cradle.iitc_mobile;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
/**
* this class manages automatic login using the Google account stored on the device
*/
public class IITC_DeviceAccountLogin implements AccountManagerCallback<Bundle> {
/**
* Adapter to show available accounts in a ListView. Accounts are read from mAccounts
*/
private class AccountAdapter extends BaseAdapter {
@Override
public int getCount() {
return mAccounts.length;
}
@Override
public Account getItem(int position) {
return mAccounts[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = mActivity.getLayoutInflater();
View v = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
TextView tv = (TextView) v.findViewById(android.R.id.text1);
tv.setText(mAccounts[position].name);
return tv;
}
}
private Account mAccount;
private final AccountAdapter mAccountAdapter;
private final AccountManager mAccountManager;
private Account[] mAccounts;
private final IITC_Mobile mActivity;
private String mAuthToken;
private final AlertDialog mProgressbar;
private final WebView mWebView;
/**
* This listener is invoked when an item in the account list is selected. (It is also used when the 'cancel' button
* is clicked, (in which case `index` is <0)
*/
private final DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int index) {
if (index >= 0 && index < mAccounts.length) {
mAccount = mAccounts[index];
startAuthentication();
}
dialog.cancel();
}
};
public IITC_DeviceAccountLogin(IITC_Mobile activity, WebView webView, WebViewClient webViewClient) {
mActivity = activity;
mWebView = webView;
mAccountManager = AccountManager.get(activity);
mAccountAdapter = new AccountAdapter();
// dialog that serves as a progress bar overlay
mProgressbar = new AlertDialog.Builder(mActivity)
.setCancelable(false)
.setView(mActivity.getLayoutInflater().inflate(R.layout.dialog_progressbar, null))
.create();
}
/**
* display all available accounts to the user
*/
private void displayAccountList() {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity)
.setTitle(R.string.choose_account_to_login)
.setSingleChoiceItems(mAccountAdapter, 0, onClickListener)
.setNegativeButton(android.R.string.cancel, onClickListener);
AlertDialog dialog = builder.create();
dialog.show();
}
/**
* called when something failed. Shows a toast message. Classic login is still available
*/
private void onLoginFailed() {
Toast.makeText(mActivity, R.string.login_failed, Toast.LENGTH_SHORT).show();
}
/**
* called to start authenticating using AccountManager.
* <p/>
* After a token is created, AccountManager will call the run() method.
*/
private void startAuthentication() {
mProgressbar.show();
mAccountManager.getAuthToken(mAccount, mAuthToken, null, mActivity, this, null);
}
/**
* called by IITC_Mobile when the authentication activity has finished.
*/
public void onActivityResult(int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK)
// authentication activity succeeded, request token again
startAuthentication();
else
onLoginFailed();
}
/**
* called by AccountManager
*/
@Override
public void run(AccountManagerFuture<Bundle> value) {
mProgressbar.hide();
try {
Intent launch = (Intent) value.getResult().get(AccountManager.KEY_INTENT);
if (launch != null) {
// There is a reason we need to start the given activity if we want an authentication token.
// (Could be user confirmation or something else. Whatever, we have to start it)
// IITC_Mobile will call it using startActivityForResult
mActivity.startLoginActivity(launch);
return;
}
String result = value.getResult().getString(AccountManager.KEY_AUTHTOKEN);
if (result != null) {
// authentication succeded, we can load the given url, which will redirect back to the intel map
mWebView.loadUrl(result);
mActivity.loginSucceeded();
} else {
onLoginFailed();
}
} catch (Exception e) {
onLoginFailed();
}
}
/**
* start authentication
* <p/>
* if we already have a username (e.g. because the existing login has timed out), we can directly start
* authentication if an account with that username is found.
*/
public void startLogin(String realm, String accountName, String args) {
mAccounts = mAccountManager.getAccountsByType(realm);
mAccountAdapter.notifyDataSetChanged();
mAuthToken = "weblogin:" + args;
if (mAccounts.length == 0) {
return;
}
for (Account account : mAccounts) {
if (account.name.equals(accountName)) {
mAccountManager.getAuthToken(account, mAuthToken, null, mActivity, this, null);
return;
}
}
displayAccountList();
}
}