org.sirimangalo.meditationplus.ActivityMain.java Source code

Java tutorial

Introduction

Here is the source code for org.sirimangalo.meditationplus.ActivityMain.java

Source

/*
This file is part of MeditationPlus.
    
MeditationPlus is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
MeditationPlus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with MeditationPlus.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.sirimangalo.meditationplus;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.os.ResultReceiver;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ShareCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.NumberPicker;
import android.widget.ShareActionProvider;
import android.widget.TextView;
import android.widget.Toast;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

public class ActivityMain extends ActionBarActivity
        implements ActionBar.TabListener, View.OnClickListener, View.OnLongClickListener {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;

    private static String TAG = "ActivityMain";
    private static SharedPreferences prefs;
    private int LOGIN_CODE = 555;

    private static String username;
    private String password;
    private String loginToken;

    private ListView chatList;
    private static ListView medList;
    private ListView commitList;
    private TextView onlineList;
    private static LinearLayout smiliesShell;

    private boolean isShowing = false;

    private int listVersion = -1;
    private int chatVersion = -1;
    private int logVersion = -1;
    private int commitVersion = -1;

    private static ActivityMain context;
    private static NumberPicker sittingPicker;
    private static NumberPicker walkingPicker;
    private int refreshCount = 0;

    public static Button medButton;

    private JSONArray jsonChats;
    private static JSONArray jsonList;
    private JSONArray jsonLogged;
    private JSONArray jsonCommit;

    private String lastSubmit = "";
    private static GridView smilies;
    private int fullRefreshPeriod = 60;
    private int refreshPeriod = 10;
    private CountDownTimer ct;
    private boolean restartTimer;
    private int currentPosition;
    private int lastChatTime = 0;
    private boolean newChats = false;
    private boolean firstPage = true;

    ArrayList<JSONObject> lastChatArray = new ArrayList<JSONObject>();

    public boolean isAdmin = false;
    private PostTaskRunner postTask;

    private int lastWalking;
    private int lastSitting;
    private boolean startMeditating = false;

    private ScheduleClient scheduleClient;
    private AlarmManager mAlarmMgr;
    public NotificationManager mNM;

    private ProgressDialog loadingDialog;

    public static String special = "none";
    private static ArrayList<JSONObject> medArray;
    private InputMethodManager inputManager;

    private ArrayList<JSONObject> myCommitments;
    public static ArrayList<Boolean> openCommitments = new ArrayList<Boolean>();
    private ShareActionProvider mShareActionProvider;

    MyResultReceiver resultReceiver;
    private boolean doChatScroll = true;
    private boolean doingLogin = false;

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

        inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);

        context = this;

        prefs = PreferenceManager.getDefaultSharedPreferences(this);

        postTask = new PostTaskRunner(postHandler, this);

        // Create a new service client and bind our activity to this service
        scheduleClient = new ScheduleClient(this);
        scheduleClient.doBindService();

        mAlarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        mNM = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        setContentView(R.layout.activity_main);

        onlineList = (TextView) findViewById(R.id.online);

        resultReceiver = new MyResultReceiver(null);

        // loading dialog
        loadingDialog = new ProgressDialog(this);
        loadingDialog.setTitle(R.string.processing);

        // Set up the action bar.
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {

                // close keyboard

                View view = getCurrentFocus();
                if (view != null) {
                    inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                }

                // reset chat title

                if (position == 1 && newChats) {
                    if (actionBar.getTabAt(1) != null)
                        actionBar.getTabAt(1)
                                .setText(getString(R.string.title_section2).toUpperCase(Locale.getDefault()));
                    newChats = false;
                }

                currentPosition = position;
                actionBar.setSelectedNavigationItem(position);
            }
        });
        mViewPager.setOffscreenPageLimit(2);

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            actionBar
                    .addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
        }
        username = prefs.getString("username", "");
        loginToken = prefs.getString("login_token", "");
        if (loginToken.equals(""))
            showLogin();

    }

    @Override
    protected void onResume() {
        super.onResume();
        isShowing = true;
        listVersion = -1;
        chatVersion = -1;
        restartTimer = true;

        refreshPeriod = Integer.parseInt(prefs.getString("refresh_period", "10")) * 1000;
        refreshPeriod = Math.max(refreshPeriod, 10);

        fullRefreshPeriod = Integer.parseInt(prefs.getString("full_refresh_period", "60")) * 1000;
        fullRefreshPeriod = Math.max(fullRefreshPeriod, 60);

        if (ct != null)
            ct.cancel();

        ct = new CountDownTimer(fullRefreshPeriod, refreshPeriod) {
            @Override
            public void onTick(long l) {
                ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
                if (l < fullRefreshPeriod - refreshPeriod && isShowing) {
                    doSubmit(null, nvp, false);
                }
            }

            @Override
            public void onFinish() {
                if (isShowing) {
                    listVersion = -1;
                    chatVersion = -1;
                    restartTimer = true;
                    ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
                    nvp.add(new BasicNameValuePair("full_update", "true"));
                    doSubmit(null, nvp, false);
                }
            }
        };
        loginToken = prefs.getString("login_token", "");

        if (loginToken.equals("")) {
            Intent i = new Intent(this, ActivityMain.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            if (!doingLogin)
                startActivity(i);
        } else {
            username = prefs.getString("username", "");
            password = "";
            doSubmit(null, new ArrayList<NameValuePair>(), false);
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        isShowing = false;
    }

    @Override
    protected void onStop() {
        // When our activity is stopped ensure we also stop the connection to the service
        // this stops us leaking our activity into the system *bad*

        if (scheduleClient != null)
            scheduleClient.doUnbindService();
        super.onStop();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        Intent i;

        switch (id) {
        case R.id.action_htm:
            Utils.openHTM(this);
            return true;
        case R.id.action_refresh:
            listVersion = -1;
            chatVersion = -1;
            restartTimer = true;
            ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
            nvp.add(new BasicNameValuePair("full_update", "true"));
            doSubmit(null, nvp, true);
            return true;
        case R.id.action_profile:
            showProfile(username);
            return true;
        case R.id.action_schedule:
            i = new Intent(this, ActivitySchedule.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            return true;
        case R.id.action_settings:
            i = new Intent(this, ActivityPrefs.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            return true;
        case R.id.action_help:
            i = new Intent(this, ActivityHelp.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            return true;
        case R.id.action_share:

            String playStoreLink = "https://play.google.com/store/apps/details?id=" + getPackageName();
            String yourShareText = playStoreLink;
            Intent shareIntent = ShareCompat.IntentBuilder.from(this).setType("text/plain").setText(yourShareText)
                    .setSubject("Meditation Plus").getIntent();
            // Set the share Intent
            startActivity(Intent.createChooser(shareIntent, "Share App via"));
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    private int singleClick = 0;

    @Override
    public void onClick(View view) {
        int id = view.getId();
        ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
        switch (id) {
        case R.id.chat_send:

            smiliesShell.setVisibility(View.GONE);
            EditText message = (EditText) findViewById(R.id.chat_text);
            String messageT = message.getText().toString();
            if (messageT.length() == 0) {
                Toast.makeText(this, R.string.no_message, Toast.LENGTH_SHORT).show();
                return;
            }
            if (messageT.length() > 140) {
                Toast.makeText(this, R.string.message_too_long, Toast.LENGTH_SHORT).show();
                return;
            }
            nvp.add(new BasicNameValuePair("message", messageT));
            doSubmit("chatform", nvp, true);
            doChatScroll = true;
            break;
        case R.id.med_send:
            int w = walkingPicker.getValue();
            int s = sittingPicker.getValue();

            if (w == 0 && s == 0) {
                Toast.makeText(this, R.string.no_time, Toast.LENGTH_SHORT).show();
                return;
            }

            SharedPreferences.Editor editor = prefs.edit();
            editor.putInt("walking", w);
            editor.putInt("sitting", s);
            editor.apply();

            lastWalking = w * 5;
            lastSitting = s * 5;

            startMeditating = true;

            nvp.add(new BasicNameValuePair("walking", lastWalking + ""));
            nvp.add(new BasicNameValuePair("sitting", lastSitting + ""));
            doSubmit("timeform", nvp, true);
            break;
        case R.id.med_cancel:

            Intent rIntent = new Intent(this, ReceiverAlarm.class);
            PendingIntent walkPendingIntent = PendingIntent.getBroadcast(context, 0, rIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            PendingIntent sitPendingIntent = PendingIntent.getBroadcast(context, 1, rIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            mAlarmMgr.cancel(walkPendingIntent);
            mAlarmMgr.cancel(sitPendingIntent);
            mNM.cancelAll();

            doSubmit("cancelform", nvp, true);
            break;
        case R.id.smily_button:
            if (smiliesShell.getVisibility() == View.GONE)
                smiliesShell.setVisibility(View.VISIBLE);
            else
                smiliesShell.setVisibility(View.GONE);
            break;
        case R.id.chat_text:
            smiliesShell.setVisibility(View.GONE);
            singleClick++;
            Handler handler = new Handler();
            Runnable r = new Runnable() {

                @Override
                public void run() {
                    singleClick = 0;
                }
            };

            if (singleClick == 1) {
                //Single click
                handler.postDelayed(r, 250);
            } else if (singleClick == 2) {
                //Double click
                singleClick = 0;
                ((EditText) findViewById(R.id.chat_text)).setText("");
            }
            break;
        case R.id.new_commit:
            Intent i = new Intent(this, ActivityCommit.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            break;
        default:
            smiliesShell.setVisibility(View.GONE);
            break;
        }
    }

    @Override
    public boolean onLongClick(View view) {
        int id = view.getId();
        ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
        switch (id) {
        case R.id.med_send:
            nvp.add(new BasicNameValuePair("type", special.equals("love") ? "none" : "love"));

            doSubmit("change_type", nvp, true);
            return true;
        }
        return false;
    }

    public void showLoading(boolean show) {
        if (loadingDialog != null && loadingDialog.isShowing())
            loadingDialog.dismiss();

        if (!show)
            return;

        loadingDialog = new ProgressDialog(this);
        loadingDialog.setTitle(R.string.processing);
        loadingDialog.setMessage(getString(R.string.loading_message));
        loadingDialog.show();

    }

    private void showLogin() {
        doingLogin = true;
        Intent i = new Intent(this, ActivityLogin.class);
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivityForResult(i, LOGIN_CODE);
    }

    private void doLogin() {

        ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
        nvp.add(new BasicNameValuePair("password", password));
        nvp.add(new BasicNameValuePair("login_token", loginToken));
        nvp.add(new BasicNameValuePair("submit", "Login"));

        lastSubmit = "login";

        doPostTask(nvp);

        Log.d(TAG, "Executing: login");
    }

    private void doRegister() {

        ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
        nvp.add(new BasicNameValuePair("password", password));
        nvp.add(new BasicNameValuePair("submit", "Register"));

        lastSubmit = "register";

        doPostTask(nvp);

        Log.d(TAG, "Executing: login");
    }

    public void doSubmit(String formId, ArrayList<NameValuePair> nvp, boolean loading) {

        nvp.add(new BasicNameValuePair("login_token", loginToken));
        nvp.add(new BasicNameValuePair("list_version", listVersion + ""));
        nvp.add(new BasicNameValuePair("chat_version", chatVersion + ""));
        nvp.add(new BasicNameValuePair("last_chat", lastChatTime + ""));
        nvp.add(new BasicNameValuePair("submit", "Refresh"));

        if (formId == null)
            lastSubmit = "";
        else {
            nvp.add(new BasicNameValuePair("form_id", formId));
            lastSubmit = formId;
        }

        if (listVersion == -1 && chatVersion == -1)
            nvp.add(new BasicNameValuePair("full_update", "true"));

        if (loading)
            showLoading(true);

        doPostTask(nvp);
    }

    public void doPostTask(ArrayList<NameValuePair> nvp) {

        nvp.add(new BasicNameValuePair("username", username));
        nvp.add(new BasicNameValuePair("source", "android"));
        postTask.doPostTask(nvp);
    }

    public void setCommitVisible(int position, boolean visible) {
        openCommitments.set(position, visible);
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            return PlaceholderFragment.newInstance(position + 1);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
            case 0:
                return getString(R.string.title_section1).toUpperCase(l);
            case 1:
                return getString(R.string.title_section2).toUpperCase(l);
            case 2:
                return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);

            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View rootView;

            int section = getArguments().getInt(ARG_SECTION_NUMBER);

            switch (section) {
            case 2:
                rootView = inflater.inflate(R.layout.fragment_chat, container, false);
                Button chatButton = (Button) rootView.findViewById(R.id.chat_send);
                chatButton.setOnClickListener(context);

                Button smilyButton = (Button) rootView.findViewById(R.id.smily_button);
                smilyButton.setOnClickListener(context);

                final TextView chatInput = (TextView) rootView.findViewById(R.id.chat_text);

                chatInput.setOnClickListener(context);

                smiliesShell = (LinearLayout) rootView.findViewById(R.id.smilies_shell);

                smilies = (GridView) rootView.findViewById(R.id.smilies);
                smilies.setAdapter(new AdapterImage(context));
                smilies.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                        String[] s = context.getResources().getStringArray(R.array.smily_tags);
                        chatInput.setText(chatInput.getText() + s[position]);
                        smiliesShell.setVisibility(View.GONE);
                    }
                });
                break;
            case 3:
                rootView = inflater.inflate(R.layout.fragment_commit, container, false);
                Button newCommit = (Button) rootView.findViewById(R.id.new_commit);
                newCommit.setOnClickListener(context);

                break;
            default:
                rootView = inflater.inflate(R.layout.fragment_main, container, false);
                walkingPicker = (NumberPicker) rootView.findViewById(R.id.walking_input);
                sittingPicker = (NumberPicker) rootView.findViewById(R.id.sitting_input);

                walkingPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
                sittingPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

                String[] numbers = getResources().getStringArray(R.array.numbers);

                walkingPicker.setMaxValue(numbers.length - 1);
                sittingPicker.setMaxValue(numbers.length - 1);
                walkingPicker.setDisplayedValues(numbers);
                sittingPicker.setDisplayedValues(numbers);

                walkingPicker.setValue(prefs.getInt("walking", 0));
                sittingPicker.setValue(prefs.getInt("sitting", 0));

                medButton = (Button) rootView.findViewById(R.id.med_send);
                medButton.setOnClickListener(context);

                medButton.setOnLongClickListener(context);

                Button cancelButton = (Button) rootView.findViewById(R.id.med_cancel);
                cancelButton.setOnClickListener(context);
                break;
            }

            return rootView;
        }
    }

    private ServiceMediaPlayer mPlayerService;
    Handler postHandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            doingLogin = false;

            showLoading(false);

            String result = (String) msg.obj;

            if (msg.what != 1) {
                Toast.makeText(context, result, Toast.LENGTH_SHORT).show();

                if (lastSubmit.equals("login") || lastSubmit.equals("register") && isShowing)
                    showLogin();

                startMeditating = false;
                return;
            }

            if (result.equals("success"))
                return;

            try {
                //Log.d(TAG,"result:"+result);
                JSONObject json = new JSONObject(result);

                if (json.has("error") && json.getString("error").length() > 0)
                    Toast.makeText(context, json.getString("error"), Toast.LENGTH_SHORT).show();

                if (json.has("list_version"))
                    listVersion = json.getInt("list_version");
                if (json.has("chat_version"))
                    chatVersion = json.getInt("chat_version");

                if (json.has("success")) {
                    int success = Integer.parseInt(json.getString("success"));
                    if (success == -1) { // not logged in
                        Log.e(TAG, "not logged in");
                        if (isShowing)
                            showLogin();
                        startMeditating = false;
                        return;
                    } else if (success == 1) {
                        if (lastSubmit.equals("chatform"))
                            ((EditText) findViewById(R.id.chat_text)).setText("");
                    }
                }
                if (json.has("admin")) {
                    if (json.get("admin") instanceof String)
                        isAdmin = json.getString("admin").equals("true");
                }
                if (json.has("live")) {

                    View liveShell = findViewById(R.id.live_feed_shell);

                    if (!json.get("live").equals("false")) {
                        final String url = json.getString("live");

                        // check service and update text

                        Intent i = new Intent(context, ServiceMediaPlayer.class);
                        i.setAction(ServiceMediaPlayer.ACTION_CHECK);
                        i.putExtra("receiver", resultReceiver);
                        startService(i);

                        liveShell.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Intent i = new Intent(context, ServiceMediaPlayer.class);
                                i.setAction(ServiceMediaPlayer.ACTION_PLAY);
                                i.putExtra("live_url", url);
                                i.putExtra("receiver", resultReceiver);
                                startService(i);
                            }
                        });
                        liveShell.setVisibility(View.VISIBLE);
                    } else {
                        Intent i = new Intent(context, ServiceMediaPlayer.class);
                        stopService(i);
                        liveShell.setVisibility(View.GONE);
                    }

                }
                if (json.has("chat")) {
                    if (json.get("chat") instanceof JSONArray)
                        jsonChats = json.getJSONArray("chat");
                    if (jsonChats == null)
                        chatVersion = -1;
                    else
                        populateChat(jsonChats, json.has("admin") && json.getString("admin").equals("true"));
                }
                if (json.has("list")) {
                    if (json.get("list") instanceof JSONArray)
                        jsonList = json.getJSONArray("list");
                    if (jsonList == null)
                        listVersion = -1;
                    else
                        populateMeds(jsonList);
                }
                if (json.has("hours")) {
                    if (json.get("hours") instanceof JSONArray)
                        jsonLogged = json.getJSONArray("hours");
                    if (jsonLogged == null)
                        logVersion = -1;
                    else
                        populateLog(jsonLogged);
                }
                if (json.has("commit")) {
                    if (json.get("commit") instanceof JSONObject) {
                        jsonCommit = json.getJSONObject("commit").getJSONArray("commitments");

                        if (jsonCommit == null)
                            commitVersion = -1;
                        else
                            populateCommit(jsonCommit);
                    }
                }
                if (json.has("logged")) {
                    populateOnline(json.getJSONArray("loggedin"));

                }
                if (json.has("login_token")) {
                    if (lastSubmit.equals("register"))
                        Toast.makeText(context, getString(R.string.registered), Toast.LENGTH_SHORT).show();

                    if (!loginToken.equals(json.getString("login_token"))) {
                        loginToken = json.getString("login_token");
                        SharedPreferences.Editor editor = prefs.edit();
                        editor.putString("login_token", loginToken);
                        editor.apply();
                    }

                    if (isShowing && (lastSubmit.equals("register") || lastSubmit.equals("login"))) {
                        doSubmit(null, new ArrayList<NameValuePair>(), false);
                        return;
                    }
                }

                // check if upcoming commitments

                if (myCommitments.size() > 0) {

                    Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                    int day = utc.get(Calendar.DAY_OF_MONTH);
                    int weekday = utc.get(Calendar.DAY_OF_WEEK);
                    int hour = utc.get(Calendar.HOUR_OF_DAY);
                    int minute = utc.get(Calendar.MINUTE);

                    int time = hour * 60 + minute;

                    int nextCommit = 60;

                    for (JSONObject obj : myCommitments) {

                        String period = obj.getString("period");
                        String t = obj.getString("time");

                        if (period.equals("daily")) {

                            if (!t.contains(":"))
                                continue;

                            String[] ta = TextUtils.split(t, ":");
                            int ah = Integer.parseInt(ta[0]);
                            int am = Integer.parseInt(ta[1]);
                            int at = ah * 60 + am;
                            int diff = at - time;
                            if (diff > 0 && diff < nextCommit) {
                                nextCommit = diff;
                            }
                        }

                    }

                    if (nextCommit < 60) {
                        findViewById(R.id.coming_commit_shell).setVisibility(View.VISIBLE);
                        ((TextView) findViewById(R.id.coming_commit)).setText(
                                nextCommit > 1 ? String.format(getString(R.string.coming_commit), nextCommit)
                                        : getString(R.string.coming_commit_1));

                    } else
                        findViewById(R.id.coming_commit_shell).setVisibility(View.GONE);
                }

            } catch (Exception e) {
                //Log.e(TAG,"ERROR");
                e.printStackTrace();
                startMeditating = false;
            }

            if (isShowing && restartTimer) {
                restartTimer = false;
                ct.start();
            }
        }
    };

    class MyResultReceiver extends ResultReceiver {
        public MyResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {

            TextView liveView = (TextView) findViewById(R.id.live_feed);

            if (resultCode == 100) {
                liveView.setText(R.string.live_available);
            } else if (resultCode == 200) {
                liveView.setText(R.string.live_connecting);
            } else {
                liveView.setText(R.string.live_playing);
            }
        }
    }

    private void populateLog(JSONArray jsonLogged) {
        Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        int hour = utc.get(Calendar.HOUR_OF_DAY);

        int max_hour = 0;
        int max_height = 100;

        LinearLayout hll = (LinearLayout) findViewById(R.id.time_log);

        if (hll == null)
            return;

        hll.removeAllViews();

        try {
            max_hour = jsonLogged.getInt(0);
            for (int i = 1; i < jsonLogged.length(); i++) {
                max_hour = Math.max(max_hour, jsonLogged.getInt(i));
            }
            for (int i = 0; i < jsonLogged.length(); i++) {
                int height = (int) Math.ceil(max_height * jsonLogged.getInt(i) / max_hour);
                LinearLayout ll = (LinearLayout) context.getLayoutInflater().inflate(R.layout.list_item_log, null);

                ImageView iv = (ImageView) ll.findViewById(R.id.min_cell);
                iv.getLayoutParams().height = height;
                iv.getLayoutParams().width = hll.getWidth() / 24;
                TextView tv = (TextView) ll.findViewById(R.id.hour_no);
                tv.setText(i + "");
                if (hour == i)
                    tv.setBackgroundColor(0xFFFFFF33);
                ImageView sv = (ImageView) ll.findViewById(R.id.space_cell);
                sv.getLayoutParams().height = 100 - height;
                hll.addView(ll);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void populateChat(JSONArray chats, boolean admin) {
        if (findViewById(R.id.chat_list) == null)
            return;
        chatList = (ListView) findViewById(R.id.chat_list);

        int newChatNo = 0;

        int latestChatTime = 0;
        ArrayList<JSONObject> chatArray = new ArrayList<JSONObject>();

        if (chats.length() < lastChatArray.size()) { // prepend old chats
            for (int i = chats.length(); i < lastChatArray.size(); i++) {
                chatArray.add(lastChatArray.get(i));
            }
        }

        for (int i = 0; i < chats.length(); i++) {
            try {
                JSONObject chat = chats.getJSONObject(i);
                latestChatTime = Integer.parseInt(chat.getString("time"));
                if (latestChatTime > lastChatTime)
                    newChatNo++;

                chatArray.add(chat);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        lastChatArray = chatArray;

        if (latestChatTime < lastChatTime)
            newChatNo = -1;

        if (admin)
            chatList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                    String cid = (String) view.findViewById(R.id.message).getTag();
                    ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
                    doSubmit("delchat_" + cid, nvp, true);
                    return true;
                }
            });

        // save index and top position
        int index = chatList.getFirstVisiblePosition();
        View v = chatList.getChildAt(0);
        int top = (v == null) ? 0 : v.getTop();

        AdapterChat adapter = new AdapterChat(this, R.layout.list_item_chat, chatArray);
        chatList.setAdapter(adapter);

        // restore index and position

        if (doChatScroll) {
            chatList.setSelection(adapter.getCount() - 1);
            doChatScroll = false;
        } else
            chatList.setSelectionFromTop(index, top);

        if (newChatNo > 0) {
            if (currentPosition != 1 && lastChatTime > 0) {
                final MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.tick);
                mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mediaPlayer) {
                        mp.release();
                    }
                });
                mp.start();
                newChats = true;
                ActionBar actionBar = getSupportActionBar();
                if (actionBar.getTabAt(1) != null)
                    actionBar.getTabAt(1).setText(
                            Html.fromHtml(getString(R.string.title_section2).toUpperCase(Locale.getDefault()) + " ("
                                    + newChatNo + ")"));
            }
        }
        lastChatTime = latestChatTime;
    }

    private void populateMeds(JSONArray meds) {
        if (findViewById(R.id.med_list) == null)
            return;
        medList = (ListView) findViewById(R.id.med_list);

        medArray = new ArrayList<JSONObject>();
        for (int i = 0; i < meds.length(); i++) {
            try {
                JSONObject med = meds.getJSONObject(i);

                if (med.getString("username").equals(username)) {
                    if (startMeditating) {
                        startMeditating = false;

                        if (lastWalking > 0 || lastSitting > 0)
                            scheduleClient.setAlarmForNotification(lastWalking, lastSitting);
                    }

                    if (med.getString("type").equals("love")) {
                        special = "love";
                        Spannable span = new SpannableString("LOVE");
                        span.setSpan(new ForegroundColorSpan(Color.RED), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        span.setSpan(new ForegroundColorSpan(Color.YELLOW), 1, 2,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        span.setSpan(new ForegroundColorSpan(Color.GREEN), 2, 3,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        span.setSpan(new ForegroundColorSpan(Color.BLUE), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        medButton.setText(span);
                    } else {
                        special = "none";
                        medButton.setText(R.string.start);
                    }

                }

                medArray.add(med);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        TextView emptyText = (TextView) findViewById(android.R.id.empty);
        medList.setEmptyView(emptyText);

        AdapterMed adapter = new AdapterMed(this, R.layout.list_item_med, medArray, postHandler);
        medList.setAdapter(adapter);
    }

    private void populateCommit(JSONArray commitJ) {
        if (findViewById(R.id.commit_list) == null)
            return;

        commitList = (ListView) findViewById(R.id.commit_list);

        myCommitments = new ArrayList<JSONObject>();

        ArrayList<JSONObject> commitArray = new ArrayList<JSONObject>();
        for (int i = 0; i < commitJ.length(); i++) {
            try {
                JSONObject commit = commitJ.getJSONObject(i);
                if (commit.getString("type").equals("repeat")) {
                    JSONObject usersJ = commit.getJSONObject("users");
                    for (int j = 0; j < usersJ.names().length(); j++) {
                        if (usersJ.names().get(j).equals(username)) {
                            myCommitments.add(commit);
                        }
                    }
                }

                if (openCommitments.size() == i) {
                    openCommitments.add(false);
                    commit.put("open", false);
                } else
                    commit.put("open", openCommitments.get(i));

                commitArray.add(commit);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        // save index and top position
        int index = commitList.getFirstVisiblePosition();
        View v = commitList.getChildAt(0);
        int top = (v == null) ? 0 : v.getTop();

        AdapterCommit adapter = new AdapterCommit(this, R.layout.list_item_commit, commitArray, username);
        commitList.setAdapter(adapter);

        // restore index and position

        commitList.setSelectionFromTop(index, top);

    }

    private void populateOnline(JSONArray onlines) {

        if (onlines.length() == 0) {
            onlineList.setVisibility(View.GONE);
            return;
        }

        onlineList.setVisibility(View.VISIBLE);

        ArrayList<JSONObject> onlineArray = new ArrayList<JSONObject>();
        ArrayList<String> onlineNamesArray = new ArrayList<String>();

        // collect into array

        for (int i = 0; i < onlines.length(); i++) {
            try {
                JSONObject a = onlines.getJSONObject(i);
                onlineArray.add(a);
                onlineNamesArray.add(a.getString("username"));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        String text = getString(R.string.online) + " ";

        // add spans

        int pos = text.length(); // start after "Online: "

        text += TextUtils.join(", ", onlineNamesArray);
        Spannable span = new SpannableString(text);

        span.setSpan(new StyleSpan(Typeface.BOLD), 0, pos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // bold the "Online: "

        Drawable android = context.getResources().getDrawable(R.drawable.android);
        android.setBounds(0, 0, 48, 32);

        for (JSONObject oneOnA : onlineArray) {
            try {
                final String oneOn = oneOnA.getString("username");

                int end = pos + oneOn.length();

                boolean isMed = false;

                for (int j = 0; j < jsonList.length(); j++) {
                    JSONObject user = jsonList.getJSONObject(j);
                    String username = user.getString("username");
                    if (username.equals(oneOn))
                        isMed = true;
                }

                if (oneOnA.getString("source").equals("android")) {
                    ImageSpan image = new ImageSpan(android, ImageSpan.ALIGN_BASELINE);
                    span.setSpan(image, pos - 1, pos, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                }

                ClickableSpan clickable = new ClickableSpan() {

                    @Override
                    public void onClick(View widget) {
                        showProfile(oneOn);
                    }

                };
                span.setSpan(clickable, pos, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

                span.setSpan(new UnderlineSpan() {
                    public void updateDrawState(TextPaint tp) {
                        tp.setUnderlineText(false);
                    }
                }, pos, end, 0);

                span.setSpan(new ForegroundColorSpan(isMed ? 0xFF009900 : 0xFFFF9900), pos, end,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                pos += oneOn.length() + 2;

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        onlineList.setText(span);
        onlineList.setMovementMethod(LinkMovementMethod.getInstance());

    }

    public void showProfile(String profile) {
        Intent i = new Intent(context, ActivityProfile.class);
        i.putExtra("profile_name", profile);
        i.putExtra("can_edit", username.equals(profile) || isAdmin);
        context.startActivity(i);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == LOGIN_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                username = data.getStringExtra("username");
                password = data.getStringExtra("password");
                String method = data.getStringExtra("method");
                if (method.equals("login"))
                    doLogin();
                else if (method.equals("register"))
                    doRegister();
            } else if (resultCode == Activity.RESULT_CANCELED) {
                finish();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

}