Java tutorial
/******************************************************************************* * Copyright 2012-2013 Trento RISE * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package eu.trentorise.smartcampus.ac.authenticator; import org.json.JSONException; import org.json.JSONObject; import android.accounts.Account; import android.accounts.AccountManager; import android.app.ProgressDialog; import android.content.ContentResolver; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.content.pm.PackageManager.NameNotFoundException; import android.os.AsyncTask; import android.os.Bundle; import android.provider.ContactsContract; import android.util.Log; import eu.trentorise.smartcampus.ac.AuthActivity; import eu.trentorise.smartcampus.ac.AuthListener; import eu.trentorise.smartcampus.ac.Constants; import eu.trentorise.smartcampus.ac.DeviceUuidFactory; import eu.trentorise.smartcampus.ac.R; import eu.trentorise.smartcampus.ac.model.UserData; import eu.trentorise.smartcampus.ac.network.RemoteConnector; /** * Implementation of the {@link AuthActivity} storing the acquired token * in the {@link AccountManager} infrastructure and broadcasting the result event. * @author raman * */ public class AuthenticatorActivity extends AuthActivity { public static final String PARAM_CONFIRM_CREDENTIALS = "confirmCredentials"; public static final String PARAM_AUTHTOKEN_TYPE = "authtokenType"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void setUp() { Intent request = getIntent(); String authTokenType = request.getStringExtra(Constants.KEY_AUTHORITY) != null ? request.getStringExtra(Constants.KEY_AUTHORITY) : Constants.AUTHORITY_DEFAULT; if (Constants.TOKEN_TYPE_ANONYMOUS.equals(authTokenType)) { new AsyncTask<Void, Void, UserData>() { private ProgressDialog progress = null; protected void onPostExecute(UserData result) { if (progress != null) { try { progress.cancel(); } catch (Exception e) { Log.w(getClass().getName(), "Problem closing progress dialog: " + e.getMessage()); } } if (result != null && result.getToken() != null) { getAuthListener().onTokenAcquired(result); } else { getAuthListener().onAuthFailed("Failed to create anonymous account"); } // TODO } @Override protected void onPreExecute() { progress = ProgressDialog.show(AuthenticatorActivity.this, "", AuthenticatorActivity.this.getString(R.string.auth_in_progress), true); super.onPreExecute(); } @Override protected UserData doInBackground(Void... params) { try { return RemoteConnector.createAnonymousUser(Constants.getAuthUrl(AuthenticatorActivity.this), new DeviceUuidFactory(AuthenticatorActivity.this).getDeviceUuid().toString()); } catch (NameNotFoundException e) { Log.e(Authenticator.class.getName(), "Failed to create anonymous user: " + e.getMessage()); return null; } } }.execute(); } else { super.setUp(); } } @Override protected AuthListener getAuthListener() { return new AMAuthListener(); } private class AMAuthListener implements AuthListener { @Override public void onTokenAcquired(UserData data) { final Account account = new Account(Constants.getAccountName(AuthenticatorActivity.this), Constants.getAccountType(AuthenticatorActivity.this)); AccountManager mAccountManager = AccountManager.get(getApplicationContext()); Bundle dataBundle = new Bundle(); try { dataBundle.putString(AccountManager.KEY_USERDATA, data.toJSON().toString()); } catch (JSONException e1) { Log.e(AuthenticatorActivity.class.getName(), "Failed to write UserData: " + e1.getMessage()); } // Account[] accounts = mAccountManager.getAccountsByType(account.type); // if (accounts != null) { // for (int i = 0; i < accounts.length; i++) { // mAccountManager.removeAccount(accounts[i], null, null); // } // } mAccountManager.addAccountExplicitly(account, null, dataBundle); // accounts = mAccountManager.getAccountsByType(account.type); ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true); Intent request = getIntent(); final String authority = request.getStringExtra(Constants.KEY_AUTHORITY) != null && !request.getStringExtra(Constants.KEY_AUTHORITY).equals(Constants.TOKEN_TYPE_ANONYMOUS) ? request.getStringExtra(Constants.KEY_AUTHORITY) : Constants.AUTHORITY_DEFAULT; mAccountManager.setAuthToken(account, authority, data.getToken()); if (request.getStringExtra(Constants.KEY_AUTHORITY).equals(Constants.TOKEN_TYPE_ANONYMOUS)) { mAccountManager.setAuthToken(account, Constants.TOKEN_TYPE_ANONYMOUS, data.getToken()); mAccountManager.setUserData(account, Constants.KEY_AUTHORITY, Constants.TOKEN_TYPE_ANONYMOUS); } else { mAccountManager.setUserData(account, Constants.KEY_AUTHORITY, authority); } final Intent intent = new Intent(); intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name); intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type); intent.putExtra(AccountManager.KEY_AUTHTOKEN, data.getToken()); // this is workaround that is needed on some devices: without it the // getuserdata may return null. the problem is with the bug in the in-memory account data caching mAccountManager.setUserData(account, AccountManager.KEY_USERDATA, dataBundle.getString(AccountManager.KEY_USERDATA)); setAccountAuthenticatorResult(intent.getExtras()); setResult(RESULT_OK, intent); IntentSender sender = request.getParcelableExtra(Constants.CALLBACK_INTENT); if (sender != null) { try { Intent add = new Intent(); add.putExtra(AccountManager.KEY_AUTHTOKEN, data.getToken()); add.putExtra(AccountManager.KEY_USERDATA, data); sender.sendIntent(AuthenticatorActivity.this, 0, add, null, null); } catch (SendIntentException e) { e.printStackTrace(); } } finish(); } @Override public void onAuthFailed(String error) { final Intent intent = new Intent(); intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, Constants.getAccountName(AuthenticatorActivity.this)); intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.getAccountType(AuthenticatorActivity.this)); intent.putExtra(AccountManager.KEY_AUTH_FAILED_MESSAGE, error); setAccountAuthenticatorResult(intent.getExtras()); setResult(Constants.RESULT_FAILURE, intent); finish(); } @Override public void onAuthCancelled() { final Intent intent = new Intent(); intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, Constants.getAccountName(AuthenticatorActivity.this)); intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.getAccountType(AuthenticatorActivity.this)); if (getIntent() != null && getIntent().hasExtra(Constants.PROMOTION_TOKEN)) { String uData = getIntent().getStringExtra(Constants.OLD_DATA); if (uData != null) { UserData data; try { data = UserData.valueOf(new JSONObject(uData)); getIntent().putExtra(Constants.KEY_AUTHORITY, Constants.TOKEN_TYPE_ANONYMOUS); onTokenAcquired(data); return; } catch (JSONException e) { Log.e(AuthenticatorActivity.class.getName(), "Failed to revert to old token: " + e.getMessage()); } } } setAccountAuthenticatorResult(intent.getExtras()); setResult(RESULT_CANCELED, intent); finish(); } } }