Android Open Source - TimeTabler Login Activity






From Project

Back to project page TimeTabler.

License

The source code is released under:

Apache License

If you think the Android project TimeTabler listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2013 Ian Kavanagh//from  w w w. j a  v  a 2  s. c  o m
 *
 * 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 ie.clashoftheash.timetabler.ui;

import ie.clashoftheash.timetabler.R;
import ie.clashoftheash.timetabler.authenticator.AccountUtils;
import ie.clashoftheash.timetabler.ui.dialogs.AccountExistsFragment;
import ie.clashoftheash.timetabler.ui.dialogs.NetworkErrorFragment;
import ie.clashoftheash.timetabler.utils.NetworkUtils;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import org.acra.ACRA;

import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;

/**
 * Activity which displays a login screen to the user
 */
public class LoginActivity extends AccountAuthenticatorActivity {

  private AccountUtils mAccounts;
  private NetworkUtils network;

  /**
   * Keep track of the login task to ensure we can cancel it if requested.
   */
  private AuthenticationTask mAuthTask = null;

  /**
   * Keep track of progress dialog so we can cancel it
   */
  private ProgressDialog mProgressDialog = null;

  // Values for programme code and year at the time of the authenticator
  // attempt.
  private String programmeCode;
  private String year;

  // UI references.
  private AutoCompleteTextView viewProgrammeCode;
  private AutoCompleteTextView viewYear;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mAccounts = new AccountUtils(this);
    network = new NetworkUtils(this);

    setContentView(R.layout.activity_login);

    findViewById(R.id.create_account).setOnClickListener(
        new View.OnClickListener() {

          @Override
          public void onClick(View v) {
            beginAuthenticaton();
          }
        });

    // Set data and sync preference settings first time app is opened
    PreferenceManager.setDefaultValues(this, R.xml.pref_data_sync, false);

    // Set up AutoCompleteTextView
    viewProgrammeCode = (AutoCompleteTextView) findViewById(R.id.programme_code);
    viewYear = (AutoCompleteTextView) findViewById(R.id.year);

    Resources res = getResources();
    String[] programmeValues = res.getStringArray(R.array.programme_codes);
    String[] yearValues = res.getStringArray(R.array.years);

    // Set programme codes
    ArrayAdapter<String> programmeAdapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, programmeValues);
    viewProgrammeCode.setAdapter(programmeAdapter);

    // Set year
    ArrayAdapter<String> yearAdapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, yearValues);
    viewYear.setAdapter(yearAdapter);

    // If done is clicked performClick on Create account button
    viewYear.setOnEditorActionListener(new TextView.OnEditorActionListener() {

      @Override
      public boolean onEditorAction(TextView v, int actionId,
          KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
          findViewById(R.id.create_account).performClick();
          return true;
        }
        return false;
      }
    });
  }

  @Override
  protected void onStart() {
    super.onStart();

    // If account exists, alert user
    if (mAccounts.accountExists())
      AppMsg.makeText(this, getString(R.string.account_already_exists),
          AppMsg.STYLE_ALERT).setLayoutGravity(Gravity.BOTTOM).show();
  }

  @Override
  public void onBackPressed() {
    // If user does not set up account, application is hidden and user is
    // sent back to where they entered the app
    if (!mAccounts.accountExists())
      moveTaskToBack(true);
    else
      super.onBackPressed();
  }

  /**
   * Begins authentication by verifying data entered, if data entered is wrong
   * errors are presented to the user and no authentication attempt is made
   */
  void beginAuthenticaton() {
    if (mAuthTask != null)
      return; // Already attempting authentication

    // Reset errors
    viewProgrammeCode.setError(null);
    viewYear.setError(null);

    // Store values at the time of the login attempt
    programmeCode = viewProgrammeCode.getText().toString();
    year = viewYear.getText().toString();

    boolean cancel = false;
    View focusView = null;

    // Check for a valid year
    if (TextUtils.isEmpty(year)) {
      viewYear.setError(getString(R.string.error_field_required));
      focusView = viewYear;
      cancel = true;
    } else if (!mAccounts.verifyYear(year)) {
      viewYear.setError(getString(R.string.error_invalid_year));
      focusView = viewYear;
      cancel = true;
    }

    // Check for a valid programme code
    if (TextUtils.isEmpty(programmeCode)) {
      viewProgrammeCode
          .setError(getString(R.string.error_field_required));
      focusView = viewProgrammeCode;
      cancel = true;
    } else if (!mAccounts.verifyProgrammeCode(programmeCode)) {
      viewProgrammeCode
          .setError(getString(R.string.error_invalid_programme_code));
      focusView = viewProgrammeCode;
      cancel = true;
    }

    if (cancel) {
      // There was an error; don't attempt login and focus the first form
      // field with an error
      focusView.requestFocus();
      return;
    }

    if (mAccounts.accountExists()) {
      AccountExistsFragment fragment = new AccountExistsFragment();

      Bundle args = new Bundle();
      args.putString(AccountExistsFragment.ARG_PROGRAMME_CODE, programmeCode);
      args.putString(AccountExistsFragment.ARG_YEAR, year);

      fragment.setArguments(args);
      fragment.show(getFragmentManager(), "AccountExistsFragment");
      return;
    }

    if (!network.connectionAvailable()) {
      NetworkErrorFragment.handleNoConnection().show(
          getFragmentManager(), "NetworkErrorFragment");
      return;
    }

    startAuthentication();
  }

  /**
   * Shows a progress dialog to the user and starts the authentication task
   */
  private void startAuthentication() {
    // Show a progress dialog
    if (mProgressDialog == null) {
      mProgressDialog = new ProgressDialog(this);
      mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      mProgressDialog
          .setMessage(getString(R.string.progress_authenticating));
      mProgressDialog.setIndeterminate(true);
      mProgressDialog.setProgressNumberFormat(null);
      mProgressDialog.setProgressPercentFormat(null);
      mProgressDialog.setOnCancelListener(new OnCancelListener() {

        public void onCancel(DialogInterface dialog) {
          if (mAuthTask != null) { // Cancel authentication task
            mAuthTask.cancel(true);
            mAuthTask = null;
          }
        }

      });
    }
    mProgressDialog.show();

    mAuthTask = new AuthenticationTask();
    mAuthTask.execute(new String[] { programmeCode, year });
  }

  private void onAuthenticationComplete(boolean result) {
    if (mAuthTask != null) {
      mAuthTask.cancel(true);
      mAuthTask = null;
    }

    mProgressDialog.dismiss();

    if (result) {
      if (mAccounts.addAccount(programmeCode, year)) {

        final Intent intent = new Intent();
        intent.putExtra(AccountManager.KEY_ACCOUNT_NAME,
            getString(R.string.account_name));
        intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,
            getString(R.string.account_type));
        setAccountAuthenticatorResult(intent.getExtras());
        setResult(RESULT_OK, intent);

        finish();
        return;
      }
    }

    AppMsg.makeText(this, getString(R.string.error_authenticating),
        AppMsg.STYLE_ALERT).setLayoutGravity(Gravity.BOTTOM).show();
  }

  /**
   * Used to verify the combination of year and programme code entered by the
   * user return a valid timetable
   * 
   * Takes the programme code and year entered by the user as arguments
   * 
   * @author Ian Kavanagh
   */
  private class AuthenticationTask extends AsyncTask<String, Void, Boolean> {
    private static final String TAG = "AuthenticationTask";

    @Override
    protected Boolean doInBackground(String... params) {

      HttpURLConnection conn = null;

      try {
        URL url = network.buildTimetableUrl(params[0], params[1], 1);
        conn = network.openConnection(url);

        if (network.connectionRedirected(url, conn)) {
          NetworkErrorFragment.handleRedirect().show(
              getFragmentManager(), "");

          return false;
        }

        return conn.getResponseCode() == HttpURLConnection.HTTP_OK;
      } catch (IllegalArgumentException e) {
        Log.e(TAG, "Invalid URL passed to openConnection", e);
        ACRA.getErrorReporter().handleSilentException(e);
        return false;
      } catch (IOException e) {
        Log.e(TAG,
            "IOException occured building url or opening connection",
            e);
        ACRA.getErrorReporter().handleSilentException(e);
        return false;
      } finally {
        if (conn != null)
          conn.disconnect();
      }
    }

    @Override
    protected void onPostExecute(Boolean success) {
      onAuthenticationComplete(success);
    }

    @Override
    protected void onCancelled() {
      mProgressDialog.dismiss();
      if (mAuthTask != null) {
        mAuthTask.cancel(true);
        mAuthTask = null;
      }
    }

  }

}




Java Source Code List

ie.clashoftheash.timetabler.TimeTablerApplication.java
ie.clashoftheash.timetabler.authenticator.AccountUtils.java
ie.clashoftheash.timetabler.authenticator.AuthenticatorService.java
ie.clashoftheash.timetabler.authenticator.Authenticator.java
ie.clashoftheash.timetabler.provider.TimetableParser.java
ie.clashoftheash.timetabler.provider.TimetableProvider.java
ie.clashoftheash.timetabler.provider.TimetableUtils.java
ie.clashoftheash.timetabler.provider.Timetable.java
ie.clashoftheash.timetabler.sync.SyncAdapter.java
ie.clashoftheash.timetabler.sync.SyncService.java
ie.clashoftheash.timetabler.ui.CreateEventActivity.java
ie.clashoftheash.timetabler.ui.EventDetailActivity.java
ie.clashoftheash.timetabler.ui.EventDetailFragment.java
ie.clashoftheash.timetabler.ui.EventListActivity.java
ie.clashoftheash.timetabler.ui.EventListFragment.java
ie.clashoftheash.timetabler.ui.LoginActivity.java
ie.clashoftheash.timetabler.ui.SettingsActivity.java
ie.clashoftheash.timetabler.ui.dialogs.AccountExistsFragment.java
ie.clashoftheash.timetabler.ui.dialogs.DatePickerFragment.java
ie.clashoftheash.timetabler.ui.dialogs.DeleteEventFragment.java
ie.clashoftheash.timetabler.ui.dialogs.NetworkErrorFragment.java
ie.clashoftheash.timetabler.ui.dialogs.RemoveAccountFragment.java
ie.clashoftheash.timetabler.ui.dialogs.TimePickerFragment.java
ie.clashoftheash.timetabler.ui.widget.AgendaAdapter.java
ie.clashoftheash.timetabler.ui.widget.SimpleSectionedListAdapter.java
ie.clashoftheash.timetabler.utils.LoadEvent.java
ie.clashoftheash.timetabler.utils.NetworkUtils.java
ie.clashoftheash.timetabler.utils.Utils.java