com.nadmm.airports.aeronav.DtppFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.nadmm.airports.aeronav.DtppFragment.java

Source

/*
 * FlightIntel for Pilots
 *
 * Copyright 2012-2016 Nadeem Hasan <nhasan@nadmm.com>
 *
 * This program 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.
 *
 * 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 com.nadmm.airports.aeronav;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.nadmm.airports.FragmentBase;
import com.nadmm.airports.R;
import com.nadmm.airports.data.DatabaseManager;
import com.nadmm.airports.utils.CursorAsyncTask;
import com.nadmm.airports.utils.DataUtils;
import com.nadmm.airports.utils.NetworkUtils;
import com.nadmm.airports.utils.SystemUtils;
import com.nadmm.airports.utils.TimeUtils;
import com.nadmm.airports.utils.UiUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

public class DtppFragment extends FragmentBase {

    protected HashMap<String, View> mDtppRowMap = new HashMap<>();
    protected ArrayList<String> mPendingCharts = new ArrayList<>();
    protected String mTppCycle;
    protected String mFaaCode;
    protected String mTppVolume;
    protected boolean mExpired = false;
    protected View.OnClickListener mOnClickListener;
    protected IntentFilter mFilter;
    protected BroadcastReceiver mReceiver;

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

        mFilter = new IntentFilter();
        mFilter.addAction(DtppService.ACTION_CHECK_CHARTS);
        mFilter.addAction(DtppService.ACTION_GET_CHARTS);

        mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                handleDtppBroadcast(intent);
            }
        };

        mOnClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String path = (String) v.getTag(R.id.DTPP_PDF_PATH);
                if (path == null) {
                    String pdfName = (String) v.getTag(R.id.DTPP_PDF_NAME);
                    getTppChart(pdfName);
                } else {
                    startPdfViewer(path);
                }
            }
        };
    }

    @Override
    public void onResume() {
        super.onResume();

        LocalBroadcastManager bm = LocalBroadcastManager.getInstance(getActivity());
        bm.registerReceiver(mReceiver, mFilter);
    }

    @Override
    public void onPause() {
        super.onPause();

        LocalBroadcastManager bm = LocalBroadcastManager.getInstance(getActivity());
        bm.unregisterReceiver(mReceiver);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dtpp_detail_view, container, false);

        Button btnDownload = (Button) view.findViewById(R.id.btnDownload);
        btnDownload.setOnClickListener(new View.OnClickListener() {

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

        Button btnDelete = (Button) view.findViewById(R.id.btnDelete);
        btnDelete.setOnClickListener(new View.OnClickListener() {

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

        return createContentView(view);
    }

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

        Bundle args = getArguments();
        String siteNumber = args.getString(DatabaseManager.Airports.SITE_NUMBER);
        setBackgroundTask(new DtppTask()).execute(siteNumber);
    }

    protected void showDtppSummary(Cursor[] result) {
        LinearLayout topLayout = (LinearLayout) findViewById(R.id.dtpp_detail_layout);

        Cursor cycle = result[1];
        cycle.moveToFirst();
        mTppCycle = cycle.getString(cycle.getColumnIndex(DatabaseManager.DtppCycle.TPP_CYCLE));
        String from = cycle.getString(cycle.getColumnIndex(DatabaseManager.DtppCycle.FROM_DATE));
        String to = cycle.getString(cycle.getColumnIndex(DatabaseManager.DtppCycle.TO_DATE));

        RelativeLayout item = (RelativeLayout) inflate(R.layout.grouped_detail_item);
        TextView tv = (TextView) item.findViewById(R.id.group_name);
        tv.setVisibility(View.GONE);
        LinearLayout layout = (LinearLayout) item.findViewById(R.id.group_details);
        addRow(layout, "Cycle", mTppCycle);

        // Parse chart cycle effective dates
        SimpleDateFormat df = new SimpleDateFormat("HHmm'Z' MM/dd/yy", Locale.US);
        df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
        Date toDate = null;
        try {
            toDate = df.parse(to);
        } catch (ParseException ignored) {
        }

        if (toDate != null) {
            addRow(layout, "Valid", TimeUtils.formatDateTime(getActivity(), toDate.getTime()));

            Cursor dtpp = result[2];
            dtpp.moveToFirst();
            String tppVolume = dtpp.getString(0);
            addRow(layout, "Volume", tppVolume);

            // Determine if chart cycle has expired
            Date now = new Date();
            if (now.getTime() > toDate.getTime()) {
                mExpired = true;
                addRow(layout, "WARNING: This chart cycle has expired.");
            }
        }

        topLayout.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
    }

    protected void showDtppCharts(Cursor[] result) {
        LinearLayout topLayout = (LinearLayout) findViewById(R.id.dtpp_detail_layout);

        int index = 3;
        while (index < result.length) {
            showChartGroup(topLayout, result[index]);
            ++index;
        }
        showOtherCharts(topLayout);

        // Check the chart availability
        ArrayList<String> pdfNames = new ArrayList<>();
        for (String pdfName : mDtppRowMap.keySet()) {
            pdfNames.add(pdfName);
        }
        checkTppCharts(pdfNames, false);
    }

    protected void showChartGroup(LinearLayout layout, Cursor c) {
        if (c.moveToFirst()) {
            String chartCode = c.getString(c.getColumnIndex(DatabaseManager.Dtpp.CHART_CODE));
            RelativeLayout item = (RelativeLayout) inflate(R.layout.grouped_detail_item);
            TextView tv = (TextView) item.findViewById(R.id.group_name);
            tv.setText(DataUtils.decodeChartCode(chartCode));
            LinearLayout group = (LinearLayout) item.findViewById(R.id.group_details);
            do {
                String chartName = c.getString(c.getColumnIndex(DatabaseManager.Dtpp.CHART_NAME));
                String pdfName = c.getString(c.getColumnIndex(DatabaseManager.Dtpp.PDF_NAME));
                String userAction = c.getString(c.getColumnIndex(DatabaseManager.Dtpp.USER_ACTION));
                String faanfd18 = c.getString(c.getColumnIndex(DatabaseManager.Dtpp.FAANFD18_CODE));
                addChartRow(group, chartCode, chartName, pdfName, userAction, faanfd18);
            } while (c.moveToNext());
            layout.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
        }
    }

    protected void showOtherCharts(LinearLayout layout) {
        RelativeLayout item = (RelativeLayout) inflate(R.layout.grouped_detail_item);
        TextView tv = (TextView) item.findViewById(R.id.group_name);
        LinearLayout group = (LinearLayout) item.findViewById(R.id.group_details);
        tv.setText("Other");
        addChartRow(group, "", "Airport Diagram Legend", "legendAD.pdf", "", "");
        addChartRow(group, "", "Legends & General Information", "frntmatter.pdf", "", "");
        layout.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
    }

    protected View addChartRow(LinearLayout layout, String chartCode, String chartName, String pdfName,
            String userAction, String faanfd18) {
        View row;
        if (userAction.length() > 0) {
            row = addRow(layout, chartName, DataUtils.decodeUserAction(userAction));
        } else {
            row = addRow(layout, chartName, faanfd18);
        }

        if (!userAction.equals("D")) {
            row.setOnClickListener(mOnClickListener);
            row.setTag(R.id.DTPP_CHART_CODE, chartCode);
            row.setTag(R.id.DTPP_PDF_NAME, pdfName);
            showChartAvailability(row, false);
            mDtppRowMap.put(pdfName, row);
        }

        row.setTag(R.id.DTPP_USER_ACTION, userAction);
        return row;
    }

    protected void checkTppCharts(ArrayList<String> pdfNames, boolean download) {
        mPendingCharts = pdfNames;
        Intent service = makeServiceIntent(DtppService.ACTION_CHECK_CHARTS);
        service.putExtra(DtppService.DOWNLOAD_IF_MISSING, download);
        getActivity().startService(service);
    }

    protected void getTppChart(String pdfName) {
        mPendingCharts.add(pdfName);
        Intent service = makeServiceIntent(DtppService.ACTION_GET_CHARTS);
        getActivity().startService(service);
    }

    protected void deleteCharts() {
        for (String pdfName : mDtppRowMap.keySet()) {
            View v = mDtppRowMap.get(pdfName);
            String userAction = (String) v.getTag(R.id.DTPP_USER_ACTION);
            String chartCode = (String) v.getTag(R.id.DTPP_CHART_CODE);
            String path = (String) v.getTag(R.id.DTPP_PDF_PATH);
            if (!userAction.equals("D") && chartCode.length() > 0 && path != null) {
                mPendingCharts.add(pdfName);
            }
        }
        Intent service = makeServiceIntent(DtppService.ACTION_DELETE_CHARTS);
        getActivity().startService(service);
    }

    protected Intent makeServiceIntent(String action) {
        Intent service = new Intent(getActivity(), DtppService.class);
        service.setAction(action);
        service.putExtra(DtppService.CYCLE_NAME, mTppCycle);
        service.putExtra(DtppService.TPP_VOLUME, mTppVolume);
        service.putExtra(DtppService.PDF_NAMES, mPendingCharts);
        return service;
    }

    protected void getMissingCharts() {
        ArrayList<String> pdfNames = new ArrayList<>();
        for (String pdfName : mDtppRowMap.keySet()) {
            View v = mDtppRowMap.get(pdfName);
            String userAction = (String) v.getTag(R.id.DTPP_USER_ACTION);
            String path = (String) v.getTag(R.id.DTPP_PDF_PATH);
            // Skip deleted and downloaded charts
            if (!userAction.equals("D") && path == null) {
                // This PDF is not available on the device
                pdfNames.add(pdfName);
            }
        }
        UiUtils.showToast(getActivity(), String.format("Downloading %d charts in the background", pdfNames.size()));
        checkTppCharts(pdfNames, true);
    }

    protected void handleDtppBroadcast(Intent intent) {
        String action = intent.getAction();
        String pdfName = intent.getStringExtra(DtppService.PDF_NAME);
        String path = intent.getStringExtra(DtppService.PDF_PATH);

        View view = mDtppRowMap.get(pdfName);
        if (view == null) {
            // We got a broadcast for a chart for some other airport
            return;
        }

        if (path != null) {
            showChartAvailability(view, true);
            view.setTag(R.id.DTPP_PDF_PATH, path);
            if (action.equals(DtppService.ACTION_GET_CHARTS)) {
                startPdfViewer(path);
            }
        } else {
            showChartAvailability(view, false);
            view.setTag(R.id.DTPP_PDF_PATH, null);
        }

        mPendingCharts.remove(pdfName);
        if (mPendingCharts.isEmpty()) {
            updateButtonState();
        }
    }

    protected void showChartAvailability(View view, boolean available) {
        TextView tv = (TextView) view.findViewById(R.id.item_label);
        if (available) {
            UiUtils.setDefaultTintedTextViewDrawable(tv, R.drawable.ic_check_box);
        } else {
            UiUtils.setDefaultTintedTextViewDrawable(tv, R.drawable.ic_check_box_outline_blank);
        }
    }

    protected void updateButtonState() {
        // Check if we have all the charts for this airport
        boolean all = true;
        boolean none = true;
        for (String key : mDtppRowMap.keySet()) {
            View v = mDtppRowMap.get(key);
            String path = (String) v.getTag(R.id.DTPP_PDF_PATH);
            String chartCode = (String) v.getTag(R.id.DTPP_CHART_CODE);
            if (chartCode.length() > 0) {
                if (path == null) {
                    all = false;
                } else {
                    none = false;
                }
            }
        }

        Button btnDownload = (Button) findViewById(R.id.btnDownload);
        if (all) {
            btnDownload.setVisibility(View.GONE);
        } else {
            btnDownload.setVisibility(View.VISIBLE);
        }

        Button btnDelete = (Button) findViewById(R.id.btnDelete);
        if (none) {
            btnDelete.setVisibility(View.GONE);
        } else {
            btnDelete.setVisibility(View.VISIBLE);
        }
    }

    protected void getAptCharts() {
        NetworkUtils.checkNetworkAndDownload(getActivity(), new Runnable() {

            @Override
            public void run() {
                getMissingCharts();
            }
        });
    }

    protected void startPdfViewer(String path) {
        if (mExpired) {
            UiUtils.showToast(getActivity(), "WARNING: This chart has expired!");
        }
        SystemUtils.startPDFViewer(getActivity(), path);
    }

    protected void checkDelete() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage("Delete all downloaded charts for this airport?")
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        deleteCharts();
                    }
                }).setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    private final class DtppTask extends CursorAsyncTask {

        @Override
        protected Cursor[] doInBackground(String... params) {
            String siteNumber = params[0];
            int index = 0;

            Cursor[] result = new Cursor[11];

            Cursor apt = getAirportDetails(siteNumber);
            result[index++] = apt;

            mFaaCode = apt.getString(apt.getColumnIndex(DatabaseManager.Airports.FAA_CODE));

            SQLiteDatabase db = getDatabase(DatabaseManager.DB_DTPP);

            SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
            builder.setTables(DatabaseManager.DtppCycle.TABLE_NAME);
            Cursor c = builder.query(db, new String[] { "*" }, null, null, null, null, null, null);
            result[index++] = c;

            builder = new SQLiteQueryBuilder();
            builder.setTables(DatabaseManager.Dtpp.TABLE_NAME);
            c = builder.query(db, new String[] { DatabaseManager.Dtpp.TPP_VOLUME },
                    DatabaseManager.Dtpp.FAA_CODE + "=?", new String[] { mFaaCode },
                    DatabaseManager.Dtpp.TPP_VOLUME, null, null, null);
            result[index++] = c;

            c.moveToFirst();
            mTppVolume = c.getString(c.getColumnIndex(DatabaseManager.Dtpp.TPP_VOLUME));

            for (String chartCode : new String[] { "APD", "MIN", "STAR", "IAP", "DP", "DPO", "LAH", "HOT" }) {
                builder = new SQLiteQueryBuilder();
                builder.setTables(DatabaseManager.Dtpp.TABLE_NAME);
                c = builder.query(db, new String[] { "*" },
                        DatabaseManager.Dtpp.FAA_CODE + "=? AND " + DatabaseManager.Dtpp.CHART_CODE + "=?",
                        new String[] { mFaaCode, chartCode }, null, null, null, null);
                result[index++] = c;
            }

            return result;
        }

        @Override
        protected boolean onResult(Cursor[] result) {
            Cursor apt = result[0];
            showAirportTitle(apt);
            showDtppSummary(result);
            showDtppCharts(result);
            setFragmentContentShown(true);
            return true;
        }

    }

}