me.diskstation.ammon.gpsrunner.ui.CalendarFragment.java Source code

Java tutorial

Introduction

Here is the source code for me.diskstation.ammon.gpsrunner.ui.CalendarFragment.java

Source

/*
 * Copyright (c) Marco Ammon 2015.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as published by
 * the Free Software Foundation.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package me.diskstation.ammon.gpsrunner.ui;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v13.app.FragmentCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;

import java.util.ArrayList;
import java.util.Calendar;

import me.diskstation.ammon.gpsrunner.R;
import me.diskstation.ammon.gpsrunner.db.LocationDBHelper;
import me.diskstation.ammon.gpsrunner.db.LocationDBReader;
import me.diskstation.ammon.gpsrunner.db.Run;
import me.diskstation.ammon.gpsrunner.misc.CSVRunExporter;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link CalendarFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class CalendarFragment extends Fragment implements AdapterView.OnItemClickListener,
        AbsListView.MultiChoiceModeListener, FragmentCompat.OnRequestPermissionsResultCallback {
    private long selectedDate;
    private Spinner yearSpinner;
    private Spinner monthSpinner;
    private RunsListAdapter mAdapter;
    private ListView mListView;
    private Bundle spinnerSelections;
    private View mSpinnerLayout;
    private boolean selectionMode = false;
    private Long[] exportRunIds;
    private final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;

    public static CalendarFragment newInstance() {
        return new CalendarFragment();
    }

    public CalendarFragment() {
        // Required empty public constructor
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_calendar, container, false);
        mSpinnerLayout = inflater.inflate(R.layout.spinner_header, null);
        mListView = (ListView) view.findViewById(R.id.runsListView);
        mListView.addHeaderView(mSpinnerLayout);
        spinnerSelections = new Bundle();
        //initializing spinners with ArrayAdapters getting values from string arrays
        yearSpinner = (Spinner) mSpinnerLayout.findViewById(R.id.yearSpinner);
        ArrayAdapter<CharSequence> yearAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.years_array,
                R.layout.spinner_item);
        yearAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        yearSpinner.setAdapter(yearAdapter);
        yearSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                int year = position + 2015;
                spinnerSelections.putInt("spinner_selection_year", year);
                refreshList(getRuns(spinnerSelections));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        Calendar c = Calendar.getInstance();
        int currentYear = c.get(Calendar.YEAR);
        yearSpinner.setSelection(currentYear - 2015);
        spinnerSelections.putInt("spinner_selection_year", currentYear);
        monthSpinner = (Spinner) mSpinnerLayout.findViewById(R.id.monthSpinner);
        ArrayAdapter<CharSequence> monthAdapter = ArrayAdapter.createFromResource(getActivity(),
                R.array.months_array, R.layout.spinner_item);
        monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        monthSpinner.setAdapter(monthAdapter);
        monthSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                spinnerSelections.putInt("spinner_selection_month", position);
                refreshList(getRuns(spinnerSelections));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        int currentMonth = c.get(Calendar.MONTH); //starts with 0
        monthSpinner.setSelection(currentMonth); //also starts with 0
        spinnerSelections.putInt("spinner_selection_month", currentMonth);
        mAdapter = new RunsListAdapter(getActivity(), getRuns(spinnerSelections));
        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener(this);
        //mListView.setOnItemLongClickListener(this);
        //mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); moved to onLongClickListener
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        mListView.setMultiChoiceModeListener(this);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedStateInstance) {
        super.onActivityCreated(savedStateInstance);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putInt("spinner_selection_year", spinnerSelections.getInt("spinner_selection_year"));
        outState.putInt("spinner_selection_month", spinnerSelections.getInt("spinner_selection_month"));
        super.onSaveInstanceState(outState);
    }

    protected void refreshList(ArrayList<Run> runs) {
        //resets checked items
        //mListView.setItemChecked(-1, true);
        selectionMode = false;
        mAdapter.clear();
        mAdapter.addAll(runs);
    }

    protected ArrayList<Run> getRuns(final Bundle args) {
        int year = args.getInt("spinner_selection_year");
        int month = args.getInt("spinner_selection_month");
        Calendar calendar = Calendar.getInstance();
        if (year != 0) {
            calendar.set(Calendar.YEAR, year);
        }
        if (month != 0) {
            calendar.set(Calendar.MONTH, month);
        }
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
        long startTimestamp = calendar.getTimeInMillis();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
        long endTimestamp = calendar.getTimeInMillis();
        LocationDBHelper dbHelp = new LocationDBHelper(getActivity());
        LocationDBReader dbRead = new LocationDBReader(dbHelp);
        return dbRead.getRuns(startTimestamp, endTimestamp, "ASC");
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (!selectionMode) {
            //Call DetailsTabActivity with runIds = id;
            Intent intent = new Intent(getActivity(), DetailsTabActivity.class);
            Run selectedRun = (Run) parent.getItemAtPosition(position);
            //Run testRun = (Run) parent.getSelectedItem();
            long[] runIds = { selectedRun.id };
            intent.putExtra("run_ids", runIds);
            startActivity(intent);
        }
    }

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.menu_calendar_contextual, menu);
        selectionMode = true;
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        //Run selectedRun = (Run) parent.getItemAtPosition(position);
        //Run testRun = (Run) parent.getSelectedItem();
        ArrayList<Long> selectedIds = new ArrayList<>();
        SparseBooleanArray selections = mListView.getCheckedItemPositions();
        for (int i = 0; i <= mAdapter.getCount(); i++) {
            if (selections.get(i)) {
                Run selectedRun = (Run) mListView.getItemAtPosition(i);
                selectedIds.add(selectedRun.id);
            }
        }
        long[] runIds = new long[selectedIds.size()];
        for (int i = 0; i < selectedIds.size(); i++) {
            runIds[i] = selectedIds.get(i);
        }

        switch (item.getItemId()) {
        case R.id.item_open:
            //Call DetailsTabActivity with runIds = id;
            Intent intent = new Intent(getActivity(), DetailsTabActivity.class);
            intent.putExtra("run_ids", runIds);
            startActivity(intent);
            mode.finish();
            return true;
        case R.id.item_export_csv:

            exportRunIds = new Long[runIds.length];
            for (int i = 0; i < exportRunIds.length; i++) {
                exportRunIds[i] = runIds[i];
            }
            if (ContextCompat.checkSelfPermission(getActivity(),
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {

                exportRuns();
            } else {
                requestPermissions(new String[] { Manifest.permission.READ_CONTACTS },
                        WRITE_EXTERNAL_STORAGE_REQUEST);

            }
            mode.finish();
            return true;
        default:
            return false;
        }
    }

    private void exportRuns() {
        //Create CSVRunExporter and export selected runs
        CSVRunExporter csv = new CSVRunExporter(getActivity());
        csv.export(exportRunIds);
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        selectionMode = false;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
        case WRITE_EXTERNAL_STORAGE_REQUEST:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                exportRuns();
            }
            break;
        }

    }

}