liqui.droid.activity.LiquiDroid.java Source code

Java tutorial

Introduction

Here is the source code for liqui.droid.activity.LiquiDroid.java

Source

/*
 * Copyright 2012 Jakob Flierl
 *
 * 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 liqui.droid.activity;

import java.lang.ref.WeakReference;

import lfapi.v2.schema.SysInfo;
import lfapi.v2.services.LiquidFeedbackException;
import lfapi.v2.services.LiquidFeedbackService.SessionService;
import lfapi.v2.services.LiquidFeedbackService.SysInfoService;
import lfapi.v2.services.auth.SessionKeyAuthentication;
import lfapi.v2.services.LiquidFeedbackServiceFactory;
import liqui.droid.Constants;
import liqui.droid.db.DBProvider;
import liqui.droid.db.DBSystem;
import liqui.droid.db.DBSystemProvider;
import liqui.droid.service.AccountAuthenticatorService;
import liqui.droid.service.SyncService;
import liqui.droid.R;

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;

import android.accounts.Account;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

/**
 * The Class LiquiDroid.
 */
public class LiquiDroid extends Base implements OnItemSelectedListener, LoaderManager.LoaderCallbacks<Cursor> {

    public static final Uri INSTANCE_CONTENT_URI = DBSystemProvider.INSTANCE_CONTENT_URI;

    public static final Uri ACCOUNT_CONTENT_URI = DBSystemProvider.ACCOUNT_CONTENT_URI;

    protected SimpleCursorAdapter mAdapter;

    protected Spinner mSpinnerLQFBs;

    protected EditText mEditTextApiKey;

    protected Button mButtonLogin;

    protected ProgressDialog mProgressDialog;

    /**
     * The Class PasswordTextWatcher.
     */
    class PasswordTextWatcher implements TextWatcher {

        private boolean ok = false;

        /* (non-Javadoc)
         * @see android.text.TextWatcher#afterTextChanged(android.text.Editable)
         */
        @Override
        public void afterTextChanged(Editable s) {
            /* empty */
        }

        /* (non-Javadoc)
         * @see android.text.TextWatcher#beforeTextChanged(java.lang.CharSequence, int, int, int)
         */
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            /* empty */
        }

        /* (non-Javadoc)
         * @see android.text.TextWatcher#onTextChanged(java.lang.CharSequence, int, int, int)
         */
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            if (s.length() > 0) {
                ok = true;
            } else {
                ok = false;
            }

            if (s.length() > 0 && mSpinnerLQFBs.getSelectedItem() != null) {
                mButtonLogin.setEnabled(true);
            } else {
                mButtonLogin.setEnabled(false);
            }
        }

        /**
         * Checks if is ok.
         *
         * @return true, if is ok
         */
        public boolean isOk() {
            return ok;
        }

    }

    PasswordTextWatcher mPasswortTextWatcher = new PasswordTextWatcher();

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getIntent().getAction() != null
                && getIntent().getAction().equals(getString(R.string.action_login_sync))) {
            // we create a new account
        } else {
            Cursor c = getContentResolver().query(ACCOUNT_CONTENT_URI, null, "last_active = 1", null, null);

            c.moveToFirst();

            if (!c.isAfterLast()) {
                mApiName = c.getString(c.getColumnIndex(DBSystem.Account.COLUMN_NAME));
                mApiUrl = c.getString(c.getColumnIndex(DBSystem.Account.COLUMN_URL));
                mMemberId = c.getString(c.getColumnIndex(DBSystem.Account.COLUMN_MEMBER_ID));
                mSessionKey = c.getString(c.getColumnIndex(DBSystem.Account.COLUMN_SESSION_KEY));

                Log.d("XXX", "loading old session: " + mMemberId + "@" + mApiName);
            }

            c.close();
        }

        if (isAuthenticated()) {
            Intent intent = new Intent().setClass(LiquiDroid.this, MemberActivity.class);

            Bundle extras = new Bundle();
            extras.putString(Constants.Account.API_NAME, getAPIName());
            extras.putString(Constants.Account.API_URL, getAPIUrl());
            extras.putString(Constants.Account.MEMBER_ID, getMemberId());
            extras.putString(Constants.Account.SESSION_KEY, getSessionKey());
            intent.putExtras(extras);

            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);

            finish();
            return;
        }

        setContentView(R.layout.act_main);

        /*
        ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
            
        actionBar.addAction(new IntentAction(this, new Intent(getApplicationContext(),
            Search.class), R.drawable.ic_search));
                
            */

        mSpinnerLQFBs = (Spinner) findViewById(R.id.sp_lqfb_instance);

        mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, null,
                new String[] { DBSystem.Instance.COLUMN_NAME, DBSystem.Instance.COLUMN_ID },
                new int[] { android.R.id.text1 });

        mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        mSpinnerLQFBs.setAdapter(mAdapter);
        mSpinnerLQFBs.setOnItemSelectedListener(this);

        mEditTextApiKey = (EditText) findViewById(R.id.et_api_token);
        mEditTextApiKey.addTextChangedListener(mPasswortTextWatcher);

        mButtonLogin = (Button) findViewById(R.id.btn_login);
        mButtonLogin.setEnabled(false);
        mButtonLogin.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Cursor c = (Cursor) mSpinnerLQFBs.getSelectedItem();

                if (c == null)
                    return;

                mApiUrl = c.getString(c.getColumnIndex(DBSystem.Instance.COLUMN_URL));
                mApiName = c.getString(c.getColumnIndex(DBSystem.Instance.COLUMN_NAME));

                hideKeyboard(mButtonLogin.getWindowToken());

                String key = mEditTextApiKey.getText().toString().trim();
                new LoginTask(LiquiDroid.this).execute(getAPIName(), getAPIUrl(), key);
            }
        });

        TextView tvExplore = (TextView) findViewById(R.id.tv_explore);
        tvExplore.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent().setClass(LiquiDroid.this, Explore.class);

                Bundle extras = new Bundle();
                extras.putString(Constants.Account.API_NAME, mApiName);
                extras.putString(Constants.Account.API_URL, mApiUrl);
                extras.putString(Constants.Account.MEMBER_ID, mMemberId);
                extras.putString(Constants.Account.SESSION_KEY, mSessionKey);
                intent.putExtras(extras);

                startActivity(intent);
            }
        });

        if (getIntent().getAction() != null
                && getIntent().getAction().equals(getString(R.string.action_login_sync))) {
            // we create a new account

            LinearLayout llExplore = (LinearLayout) findViewById(R.id.ll_explore);
            llExplore.setVisibility(View.GONE);
        }

        getSupportLoaderManager().initLoader(0, null, this);
    }

    /**
     * The Class LoginTask.
     */
    private class LoginTask extends AsyncTask<String, Void, Void> {

        private WeakReference<LiquiDroid> mTarget;

        private boolean mException;

        private boolean isAuthError;

        private String mExceptionMsg;

        private String mApiName;

        private String mApiUrl;

        private String mApiKey;

        /**
         * Instantiates a new load repository list task.
         * 
         * @param activity the activity
         */
        public LoginTask(LiquiDroid activity) {
            mTarget = new WeakReference<LiquiDroid>(activity);
        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#doInBackground(Params[])
         */
        @Override
        protected Void doInBackground(String... params) {
            mApiName = params[0];
            mApiUrl = params[1];
            mApiKey = params[2];

            if (mTarget.get() != null) {
                try {
                    LiquidFeedbackServiceFactory factory = LiquidFeedbackServiceFactory
                            .newInstance(LoginTask.this.mApiUrl);

                    SysInfoService sis = factory.createSysInfoService();
                    SessionService ss = factory.createSessionService();
                    String sessionKey = ss.getSessionKey(mApiKey);

                    sis.setAuthentication(new SessionKeyAuthentication(sessionKey));
                    SysInfo si = sis.getInfo();

                    Log.d("XXXXXXXXX", si.toString());

                    Log.d("XXXXXX", "currentMemberId " + si.currentMemberId);
                    Log.d("XXXXXX", "currentAccessLevel " + si.currentAccessLevel);

                    if (!"member".equals(si.currentAccessLevel)) {
                        isAuthError = true;
                        throw new LiquidFeedbackException("Invalid API key", null);
                    }

                    // authenticated
                    mMemberId = String.valueOf(si.currentMemberId);
                    mSessionKey = sessionKey;

                    // clear all last active entries
                    ContentValues valuesActive = new ContentValues();
                    valuesActive.put(DBSystem.Account.COLUMN_LAST_ACTIVE, 0);
                    getContentResolver().update(ACCOUNT_CONTENT_URI, valuesActive, null, null);

                    // save last active entry and member + session values
                    ContentValues values = new ContentValues();
                    values.put(DBSystem.Account.COLUMN_NAME, mApiName);
                    values.put(DBSystem.Account.COLUMN_URL, mApiUrl);
                    values.put(DBSystem.Account.COLUMN_API_KEY, mApiKey);

                    values.put(DBSystem.Account.COLUMN_MEMBER_ID, mMemberId);
                    values.put(DBSystem.Account.COLUMN_SESSION_KEY, mSessionKey);
                    values.put(DBSystem.Account.COLUMN_LAST_ACTIVE, 1);
                    values.put(DBSystem.Account.COLUMN_META_CACHED, System.currentTimeMillis());

                    int updated = getContentResolver().update(ACCOUNT_CONTENT_URI, values,
                            DBSystem.Account.COLUMN_MEMBER_ID + " = ? AND " + DBSystem.Account.COLUMN_NAME + " = ?",
                            new String[] { mMemberId, mApiName });

                    if (updated == 0) {
                        getContentResolver().insert(ACCOUNT_CONTENT_URI, values);

                        Log.d("XXX", "updated == 0");
                    }

                    // if (!AccountAuthenticatorService.hasAccount(mTarget.get())) {
                    Account account = new Account(mMemberId + "@" + mApiName, Constants.Account.TYPE);

                    Log.d("XXX", "Adding account: " + account.toString());

                    Bundle userData = new Bundle();
                    userData.putString(Constants.Account.API_NAME, mApiName);
                    userData.putString(Constants.Account.API_URL, mApiUrl);
                    userData.putString(Constants.Account.MEMBER_ID, mMemberId);
                    userData.putString(Constants.Account.SESSION_KEY, mSessionKey);

                    Parcelable authResponse = null;
                    if (getIntent() != null && getIntent().getExtras() != null) {
                        authResponse = getIntent().getExtras().getParcelable("accountAuthenticatorResponse");
                    }

                    // add system account
                    AccountAuthenticatorService.addAccount(LiquiDroid.this, mMemberId, mApiKey, userData,
                            authResponse);

                    // add periodic sync
                    Bundle extrasPeriodic = new Bundle();
                    long syncInterval = 60 * 60 * 12; // 12 hours
                    ContentResolver.addPeriodicSync(account, DBProvider.AUTHORITY, extrasPeriodic, syncInterval);

                    // enable sync
                    ContentResolver.setSyncAutomatically(account, DBProvider.AUTHORITY, true);

                    // force sync
                    Bundle extrasForce = new Bundle();
                    extrasForce.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
                    extrasForce.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
                    ContentResolver.requestSync(account, DBProvider.AUTHORITY, extrasForce);

                    // }
                } catch (LiquidFeedbackException e) {
                    Log.e(Constants.LOG_TAG, e.getMessage(), e);

                    if (e.isForbidden()) {
                        isAuthError = true;
                    }

                    mException = true;
                    mExceptionMsg = e.getMessage();

                    if (e.getCause() != null) {
                        mExceptionMsg += ", " + e.getCause().getMessage();
                    }
                }

                return null;
            } else {
                return null;
            }
        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {
            if (mTarget.get() != null) {
                mTarget.get().mProgressDialog = ProgressDialog.show(mTarget.get(), null,
                        mTarget.get().getResources().getString(R.string.lqfb_signing_in), true, false);
            }
        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(Void result) {
            if (mTarget.get() != null) {
                LiquiDroid activity = mTarget.get();
                activity.mProgressDialog.dismiss();
                if (mException && isAuthError) {
                    Toast.makeText(activity, activity.getResources().getString(R.string.lqfb_invalid_api_key),
                            Toast.LENGTH_SHORT).show();
                } else if (mException) {
                    Toast.makeText(activity, mExceptionMsg, Toast.LENGTH_LONG).show();
                } else {
                    if (getIntent().getAction() != null
                            && getIntent().getAction().equals(getString(R.string.action_login_sync))) {

                        Log.d("XXX", "LoginTask finished.");

                        activity.finish();
                    } else {
                        Intent intent = new Intent().setClass(LiquiDroid.this, MemberActivity.class);

                        Bundle extras = new Bundle();
                        extras.putString(Constants.Account.API_NAME, mApiName);
                        extras.putString(Constants.Account.API_URL, mApiUrl);
                        extras.putString(Constants.Account.MEMBER_ID, mMemberId);
                        extras.putString(Constants.Account.SESSION_KEY, mSessionKey);
                        intent.putExtras(extras);

                        Log.d("XXX", "LoginTask start member activity.");

                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        activity.startActivity(intent);
                        activity.finish();
                    }
                }
            }
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        Cursor c = (Cursor) parent.getItemAtPosition(pos);

        String name = c.getString(c.getColumnIndex(DBSystem.Instance.COLUMN_NAME));
        String url = c.getString(c.getColumnIndex(DBSystem.Instance.COLUMN_URL));
        String key = c.getString(c.getColumnIndex(DBSystem.Instance.COLUMN_API_KEY));

        setSettingStringValue("SpinnerLogin", String.valueOf(mSpinnerLQFBs.getSelectedItemPosition()));

        mApiName = name;
        mApiUrl = url;

        mEditTextApiKey.setText(key);

        fillData();

        setActionBarTitle();
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {
        /* empty */
    }

    public void fillData() {
        TextView tvExplore = (TextView) findViewById(R.id.tv_explore);

        if (getAPIDB() != null) {
            tvExplore.setText(getString(R.string.lqfb_explore) + " " + getAPIName());
            tvExplore.setVisibility(View.VISIBLE);
        } else {
            tvExplore.setVisibility(View.GONE);
        }
    }

    class LQFBContentObserver extends ContentObserver {

        public LQFBContentObserver(Handler handler) {
            super(handler);
        }

        @Override
        public boolean deliverSelfNotifications() {
            return true;
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            fillData();
        }

    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(this, INSTANCE_CONTENT_URI, null, null, null, "_id");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
        mAdapter.swapCursor(cursor);
        if (getSettingStringValue("SpinnerLogin") != null)
            mSpinnerLQFBs.setSelection(Integer.valueOf(getSettingStringValue("SpinnerLogin")));

        fillData();
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        mAdapter.swapCursor(null);
    }

    @Override
    public void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
        case SyncService.STATUS_FINISHED: {
            fillData();
            break;
        }
        }

        super.onReceiveResult(resultCode, resultData);
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu)
     */
    @Override
    public boolean onPrepareOptionsMenu(com.actionbarsherlock.view.Menu menu) {
        menu.clear();
        com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.anon_menu, menu);
        return true;
    }

}