org.apps8os.logger.android.fragment.LoggerPanelFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.apps8os.logger.android.fragment.LoggerPanelFragment.java

Source

/**
 * Copyright (c) 2013 Aalto University and the authors
 *
 * Permission is hereby granted, free of charge, to any person obtaining 
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the 
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included 
 * in all copies or substantial portions of the Software.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 *  
 * Authors:
 * Chao Wei (chao.wei@aalto.fi)
 */
package org.apps8os.logger.android.fragment;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import org.apps8os.contextlogger3.android.app.BaseAlertDialogFragment.AlertDialogListener;
import org.apps8os.logger.android.LoggerApp;
import org.apps8os.logger.android.MainActivity;
import org.apps8os.logger.android.R;
import org.apps8os.logger.android.fragment.dialog.ActivityNameDeletionDialogFragment;
import org.apps8os.logger.android.fragment.dialog.ActivityNamingDialogFragment;
import org.apps8os.logger.android.fragment.dialog.ActivityNamingDialogFragment.ActivityNamingListener;
import org.apps8os.logger.android.fragment.dialog.EventTimePickerDialogFragment;
import org.apps8os.logger.android.fragment.dialog.EventTimePickerDialogFragment.EventTimeMode;
import org.apps8os.logger.android.fragment.dialog.EventTimePickerDialogFragment.OnEventTimeChangedListener;
import org.apps8os.logger.android.fragment.dialog.LanguageSettingDialogFragment;
import org.apps8os.logger.android.fragment.dialog.QuitAppDialogFragment;
import org.apps8os.logger.android.manager.AppManager;
import org.apps8os.logger.android.manager.AppManager.LoggerNFCBroadcastReceiver;
import org.apps8os.logger.android.model.ActionEvent;
import org.apps8os.logger.android.model.ActionEvent.EventState;
import org.apps8os.logger.android.util.AndroidVersionHelper;
import org.apps8os.logger.android.widget.adapter.ActionEventListAdapter;
import org.apps8os.logger.android.widget.adapter.ActionEventListAdapter.OnCustomEventChangeListener;
import org.holoeverywhere.LayoutInflater;
import org.holoeverywhere.app.Activity;
import org.holoeverywhere.widget.ListView;
import org.holoeverywhere.widget.Switch;
import org.json.JSONException;

import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.TextView;

public class LoggerPanelFragment extends LoggerBaseFragment
        implements OnCheckedChangeListener, ActivityNamingListener, OnItemClickListener, OnItemLongClickListener {
    private View mSwitcherView = null;
    private TextView mEventCount = null;
    private Switch mSwitch = null;
    private boolean mSwitchCheckState = false;
    private ListView mListView = null;

    private ArrayList<HashMap<String, Object>> mShownContent = null;
    private ArrayList<ActionEvent> mActionEventList = null;
    private ActionEventListAdapter mAdapter = null;

    private LoggerPanelNFCBroadcastReceiver mLoggerPanelNFCBroadcastReceiver = null;

    private Handler mHandler = new Handler();
    private Runnable mTimedTask = new Runnable() {
        @Override
        public void run() {
            List<ActionEvent> aeList = AppManager.getAllLiveEvents();
            if ((mShownContent != null) && (mAdapter != null)) {
                for (int i = 0; i < aeList.size(); i++) {
                    ActionEvent ae = aeList.get(i);
                    for (HashMap<String, Object> data : mShownContent) {
                        if (ae.getActionEventName().equals(data.get("Event"))) {
                            data.put(ActionEventListAdapter.DURATION, ae.getEventDuration());
                            data.put(ActionEventListAdapter.CHECK, true);
                            //                     data.put(ActionEventListAdapter.CUSTOM, true);
                        }
                    }
                }
                mAdapter.notifyDataSetChanged();
            }
            if ((mEventCount != null) && (aeList != null)) {
                if (aeList.isEmpty()) {
                    mEventCount.setText("0");
                } else {
                    mEventCount.setText(String.valueOf(aeList.size()));
                }
            }
            mHandler.postDelayed(mTimedTask, 850);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        if (AndroidVersionHelper.isHoneycombAbove()) {
            mLoggerPanelNFCBroadcastReceiver = new LoggerPanelNFCBroadcastReceiver();
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        getSupportActivity().getSupportActionBar().setTitle(R.string.app_name);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.frag_logger_panel, container, false);
        mListView = (ListView) view.findViewById(android.R.id.list);
        mListView.setOnItemClickListener(this);
        mListView.setOnItemLongClickListener(this);
        mSwitchCheckState = true;
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        updateEventList();
        mHandler.post(mTimedTask);
        if (mLoggerPanelNFCBroadcastReceiver != null) {
            LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(
                    mLoggerPanelNFCBroadcastReceiver, new IntentFilter(AppManager.LOGGER_INTENT_FILTER));
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        mHandler.removeCallbacks(mTimedTask);
        if (mLoggerPanelNFCBroadcastReceiver != null) {
            LocalBroadcastManager.getInstance(getApplicationContext())
                    .unregisterReceiver(mLoggerPanelNFCBroadcastReceiver);
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initCustomView();
        if (mEventCount != null) {
            mEventCount.setText("0");
            mEventCount.setVisibility(View.VISIBLE);
        }
        if (mActionEventList == null) {
            mActionEventList = new ArrayList<ActionEvent>();
            Collections.synchronizedCollection(mActionEventList);
        }
    }

    private void initCustomView() {
        mSwitcherView = null;
        mSwitch = null;
        mEventCount = null;
        mSwitcherView = getLayoutInflater().inflate(R.layout.logger_switcher, null);
        mSwitch = (Switch) mSwitcherView.findViewById(R.id.logger_switcher);
        mSwitch.setTextOn(getString(R.string.on));
        mSwitch.setTextOff(getString(R.string.off));
        mSwitch.setOnCheckedChangeListener(this);
        mSwitch.setChecked(mSwitchCheckState);
        mEventCount = (TextView) mSwitcherView.findViewById(R.id.text_view_running_event);

        // if the device is honeycomb, we need to
        // adjust the UI a little bit. Otherwise,
        // the switch would look weird.
        if (AndroidVersionHelper.isHoneycomb()) {
            final LinearLayout.LayoutParams swLp = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            swLp.setMargins(8, -20, 0, 0);
            mSwitch.setLayoutParams(swLp);
        }

        final ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
        lp.setMargins(0, 0, 16, 0);

        final ActionBar actionbar = getSupportActionBar();
        if (actionbar != null) {
            actionbar.setCustomView(mSwitcherView, lp);
            actionbar.setTitle(R.string.app_name);
        }
    }

    private void updateEventList() {
        if (mShownContent == null) {
            mShownContent = new ArrayList<HashMap<String, Object>>();
        } else {
            if (!mShownContent.isEmpty()) {
                mShownContent.clear();
            }
        }

        // read data out 
        List<String> list = new ArrayList<String>();
        try {
            list = AppManager.getEventTagsFromAsset(getApplicationContext(), AppManager.getEventTagsJsonFileResId(),
                    R.string.event_json_first_tag, R.string.event_json_second_tag);
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String tags = LoggerApp.getInstance().getEventTags();
        if (!TextUtils.isEmpty(tags)) {
            String[] strArray = tags.split(";");
            for (String str : strArray) {
                list.add(str);
            }
        }
        list.add(getString(R.string.add_your_own_event));

        for (int i = 0; i < list.size(); i++) {
            String event = list.get(i);
            HashMap<String, Object> data = new HashMap<String, Object>();
            data.put(ActionEventListAdapter.EVENT, event);
            data.put(ActionEventListAdapter.DURATION, "");
            data.put(ActionEventListAdapter.CHECK, false);
            if ((i == (list.size() - 1)) || (i < AppManager.getPreCount())) {
                data.put(ActionEventListAdapter.CUSTOM, false);
            } else {
                data.put(ActionEventListAdapter.CUSTOM, true);
            }
            mShownContent.add(data);

        }
        mAdapter = new ActionEventListAdapter(getApplicationContext(), mShownContent,
                new OnCustomEventChangeListener() {
                    @Override
                    public void onRemove(final String tag) {
                        if (TextUtils.isEmpty(tag))
                            return;
                        ActivityNameDeletionDialogFragment.newInstance(new AlertDialogListener() {
                            @Override
                            public void onPositiveClick() {
                                LoggerApp app = LoggerApp.getInstance();
                                String tags = app.getEventTags();
                                if (!TextUtils.isEmpty(tags)) {
                                    String[] strArray = tags.split(";");
                                    ArrayList<String> tagList = new ArrayList<String>(Arrays.asList(strArray));
                                    tagList.remove(tag);
                                    app.saveEventTag(
                                            tagList.isEmpty() ? null : TextUtils.join(";", tagList.toArray()));
                                    new Handler().postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            updateEventList();
                                        }
                                    }, 50L);
                                }
                            }

                            @Override
                            public void onNegativeClick() {

                            }

                            @Override
                            public void onCancel() {
                            }
                        }, tag).show(getFragmentManager());
                    }
                });
        mListView.setAdapter(mAdapter);
        mAdapter.notifyDataSetChanged();
        mListView.invalidate();
        mActionEventList = AppManager.getAllLiveEvents();
    }

    private void forceUpdateUI() {
        updateEventList();
        ((ViewGroup) getSupportActivity().getSupportActionBar().getCustomView()).removeAllViews();
        initCustomView();
        if ((mSwitch != null) && mSwitch.isChecked()) {
            AppManager.createLoggerNotification(getApplicationContext());
        }
    }

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int pos, long id) {
        if (mShownContent != null) {
            if (pos == mShownContent.size() - 1) {
                return true;
            } else {
                // check flag
                HashMap<String, Object> data = mShownContent.get(pos);
                handleLoggerData(String.valueOf(data.get(ActionEventListAdapter.EVENT)), data);
            }
        }
        return true;
    }

    void handleLoggerData(final String eventName, HashMap<String, Object> data) {
        ActionEvent actionEvent = null;
        if (!TextUtils.isEmpty(eventName)) {
            boolean hasEvent = false;
            List<ActionEvent> aeList = AppManager.getAllLiveEvents();
            if (!aeList.isEmpty()) {
                for (ActionEvent ae : aeList) {
                    if (ae.getActionEventName().equals(eventName)) {
                        hasEvent = true;
                        actionEvent = ae;
                        break;
                    }
                }
            }

            if (hasEvent) {
                // stop the event
                actionEvent.confirmBreakTimestamp();
                actionEvent.setState(ActionEvent.EventState.STOP);
                AppManager.updateLiveEvent(actionEvent);
                mActionEventList.remove(actionEvent);

                // clear the time  
                data.put(ActionEventListAdapter.DURATION, "");
                data.put(ActionEventListAdapter.CHECK, false);
            } else {
                // start the event
                actionEvent = new ActionEvent(eventName, System.currentTimeMillis());
                actionEvent.setState(ActionEvent.EventState.START);
                AppManager.addALiveEvent(actionEvent);
                mActionEventList.add(actionEvent);
                data.put(ActionEventListAdapter.CHECK, true);
            }
            AppManager.sendEventBoradcast(getApplicationContext(), actionEvent.getMessagePayload(), null);
            AppManager.scheduleCass(getApplicationContext(), actionEvent.getActionEventName(),
                    (actionEvent.getEventState().equals(EventState.START.toString()) ? true : false));
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
        if (mShownContent != null) {
            if (pos == mShownContent.size() - 1) {
                ActivityNamingDialogFragment.newInstance((ActivityNamingListener) this, new AlertDialogListener() {
                    @Override
                    public void onPositiveClick() {
                    }

                    @Override
                    public void onNegativeClick() {
                    }

                    @Override
                    public void onCancel() {
                    }
                }).show(getFragmentManager());
                return;
            } else {
                // check flag
                HashMap<String, Object> data = mShownContent.get(pos);
                final String eventName = String.valueOf(data.get(ActionEventListAdapter.EVENT));
                ActionEvent actionEvent = null;
                if (!TextUtils.isEmpty(eventName)) {
                    boolean hasEvent = false;
                    List<ActionEvent> aeList = AppManager.getAllLiveEvents();
                    if (!aeList.isEmpty()) {
                        for (ActionEvent ae : aeList) {
                            if (ae.getActionEventName().equals(eventName)) {
                                hasEvent = true;
                                actionEvent = ae;
                                break;
                            }
                        }
                    }
                    // in case, no match found, so create a new one
                    if ((actionEvent == null) && !hasEvent) {
                        actionEvent = new ActionEvent(eventName, System.currentTimeMillis());
                    }

                    final EventTimeMode em = hasEvent ? EventTimeMode.STOP : EventTimeMode.START;
                    final ActionEvent para = actionEvent;

                    EventTimePickerDialogFragment.newInstance(new OnEventTimeChangedListener() {
                        @Override
                        public void onPositiveClick() {
                        }

                        @Override
                        public void onNegativeClick() {
                        }

                        @Override
                        public void onCancel() {
                        }

                        @Override
                        public void onConfirmed(long timestamp) {
                            onEventConfirmed(em, para, timestamp);
                        }

                        @Override
                        public void onDiscard() {
                            onEventDiscard(em, para);
                        }
                    }, em, actionEvent).show(getFragmentManager());
                }
            }
        }
    }

    @Override
    public void OnTagNameInputCompleted(String tagName) {
        // save the name and refresh list 
        LoggerApp app = LoggerApp.getInstance();
        String tags = app.getEventTags();
        if (TextUtils.isEmpty(tags)) {
            tags = tagName;
        } else {
            tags = new String(tags + ";" + tagName);
        }
        app.saveEventTag(tags);
        updateEventList();
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView.getId() == R.id.logger_switcher) {
            mSwitchCheckState = isChecked;
            AppManager.toggleService(((MainActivity) getActivity()), isChecked);
            mListView.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE);
            if (!isChecked) {
                // update database and UI
                cleanUp();
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int itemId = item.getItemId();
        if (itemId == R.id.menu_shutdown) {
            QuitAppDialogFragment.newInstance(new AlertDialogListener() {
                @Override
                public void onPositiveClick() {
                    if (mSwitch != null) {
                        mSwitch.setChecked(false);
                    }

                    if (mEventCount != null) {
                        mEventCount.setText("0");
                        mEventCount.setVisibility(View.INVISIBLE);
                    }

                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            getActivity().finish();
                        }
                    }, 300L);
                }

                @Override
                public void onNegativeClick() {
                }

                @Override
                public void onCancel() {
                }
            }).show(getFragmentManager());
            return true;
        } else if (itemId == R.id.menu_export_data) {
            AppManager.exportData(((MainActivity) getActivity()));
            return true;
        } else if (itemId == R.id.menu_language_setting) {
            LanguageSettingDialogFragment.newInstance(new AlertDialogListener() {
                @Override
                public void onPositiveClick() {
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            forceUpdateUI();
                        }
                    }, 50L);
                }

                @Override
                public void onNegativeClick() {
                }

                @Override
                public void onCancel() {
                }
            }).show(getFragmentManager());
            return true;
        } else if (itemId == R.id.menu_history) {
            invokeFragmentChanged(R.layout.frag_logger_history, null);
            return true;
        } else if (itemId == R.id.menu_history2) {
            invokeFragmentChanged(R.layout.frag_logger_history2, null);
            return true;
        } else if (itemId == R.id.menu_toggle_service) {
            if (mSwitch != null) {
                final boolean disabled = !AppManager.isRunning(((MainActivity) getActivity()));
                mSwitch.setChecked(disabled);
            }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.panel_menu, menu);
        updateMenuItem(menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        updateMenuItem(menu);
    }

    private void updateMenuItem(Menu menu) {
        menu.findItem(R.id.menu_toggle_service)
                .setTitle(AppManager.isRunning(((MainActivity) getActivity())) ? R.string.stop : R.string.start);
        menu.findItem(R.id.menu_export_data).setTitle(R.string.export_data);
        menu.findItem(R.id.menu_shutdown).setTitle(R.string.quit);
        menu.findItem(R.id.menu_history).setTitle(R.string.view_history);
        menu.findItem(R.id.menu_history2).setTitle(R.string.view_history2);
        menu.findItem(R.id.menu_language_setting).setTitle(R.string.language_setting);
    }

    private void cleanUp() {
        List<ActionEvent> aeList = AppManager.getAllLiveEvents();
        // stop all the event
        for (ActionEvent ae : aeList) {
            ae.setState(ActionEvent.EventState.STOP);
            ae.confirmBreakTimestamp();
            AppManager.updateLiveEvent(ae);
            AppManager.sendEventBoradcast(getApplicationContext(), ae.getMessagePayload(), null);
            AppManager.scheduleCass(getApplicationContext(), ae.getActionEventName(), false);
            clearEventDuration(ae);
            mActionEventList.remove(ae);
        }
        mAdapter.notifyDataSetChanged();
    }

    void onEventConfirmed(EventTimeMode em, ActionEvent event, long timestamp) {
        if ((em == null) || (event == null) || (timestamp <= 0))
            return;
        ActionEvent actionEvent = null;
        if (em == EventTimeMode.START) {
            // start the event
            actionEvent = new ActionEvent(event.getActionEventName(), timestamp);
            actionEvent.setState(ActionEvent.EventState.START);
            AppManager.addALiveEvent(actionEvent);
            mActionEventList.add(actionEvent);
            event = actionEvent;
        } else if (em == EventTimeMode.STOP) {
            // stop the event
            event.setState(ActionEvent.EventState.STOP);
            event.setBreakTimestamp(timestamp);
            AppManager.updateLiveEvent(event);
            // clear the time 
            clearEventDuration(event);
            mActionEventList.remove(event);
        }
        AppManager.sendEventBoradcast(getApplicationContext(), event.getMessagePayload(), null);
        AppManager.scheduleCass(getApplicationContext(), event.getActionEventName(),
                (event.getEventState().equals(EventState.START.toString()) ? true : false));
        mAdapter.notifyDataSetChanged();
    }

    void onEventDiscard(EventTimeMode em, ActionEvent event) {
        if (event == null)
            return;
        event.confirmBreakTimestamp();
        event.setState(ActionEvent.EventState.INVALIDATE);
        AppManager.updateLiveEvent(event);
        clearEventDuration(event);
        mAdapter.notifyDataSetChanged();
        mActionEventList.remove(event);
        AppManager.sendEventBoradcast(getApplicationContext(), event.getMessagePayload(), null);
        AppManager.scheduleCass(getApplicationContext(), event.getActionEventName(), false);
    }

    private void clearEventDuration(final ActionEvent event) {
        if ((mShownContent != null) && !mShownContent.isEmpty()) {
            for (HashMap<String, Object> data : mShownContent) {
                if (event.getActionEventName().equals(String.valueOf(data.get(ActionEventListAdapter.EVENT)))) {
                    data.put(ActionEventListAdapter.DURATION, "");
                    data.put(ActionEventListAdapter.CHECK, false);
                }
            }
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // if language has changed, UI has to be reloaded
        forceUpdateUI();
    }

    private class LoggerPanelNFCBroadcastReceiver extends LoggerNFCBroadcastReceiver {

        @Override
        public void handleNfcTagEvent(String eventName) {

            HashMap<String, Object> data = null;
            for (HashMap<String, Object> d : mShownContent) {
                if (eventName.equals(d.get(ActionEventListAdapter.EVENT))) {
                    data = d;
                    break;
                }
            }

            if (data == null)
                return;

            handleLoggerData(eventName, data);
        }
    }
}