ca.rmen.android.networkmonitor.app.log.LogActionsActivity.java Source code

Java tutorial

Introduction

Here is the source code for ca.rmen.android.networkmonitor.app.log.LogActionsActivity.java

Source

/*
 * This source is part of the
 *      _____  ___   ____
 *  __ / / _ \/ _ | / __/___  _______ _
 * / // / , _/ __ |/ _/_/ _ \/ __/ _ `/
 * \___/_/|_/_/ |_/_/ (_)___/_/  \_, /
 *                              /___/
 * repository.
 *
 * Copyright (C) 2013 Benoit 'BoD' Lubek (BoD@JRAF.org)
 * Copyright (C) 2013 Carmen Alvarez (c@rmen.ca)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ca.rmen.android.networkmonitor.app.log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;

import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;

import ca.rmen.android.networkmonitor.Constants;
import ca.rmen.android.networkmonitor.R;
import ca.rmen.android.networkmonitor.app.dialog.ChoiceDialogFragment.DialogItemListener;
import ca.rmen.android.networkmonitor.app.dialog.ConfirmDialogFragment.DialogButtonListener;
import ca.rmen.android.networkmonitor.app.dialog.DialogFragmentFactory;
import ca.rmen.android.networkmonitor.app.dialog.PreferenceDialog;
import ca.rmen.android.networkmonitor.app.dialog.ProgressDialogFragment;
import ca.rmen.android.networkmonitor.app.export.CSVExport;
import ca.rmen.android.networkmonitor.app.export.DBExport;
import ca.rmen.android.networkmonitor.app.export.ExcelExport;
import ca.rmen.android.networkmonitor.app.export.FileExport;
import ca.rmen.android.networkmonitor.app.export.HTMLExport;
import ca.rmen.android.networkmonitor.app.export.SummaryExport;
import ca.rmen.android.networkmonitor.app.export.kml.KMLExport;
import ca.rmen.android.networkmonitor.provider.NetMonColumns;
import ca.rmen.android.networkmonitor.util.Log;

/**
 * Provides actions on the network monitor log: sharing and clearing the log file.
 * This activity has a transparent theme. The only thing the user will see will be alert dialogs that this activity creates.
 */
public class LogActionsActivity extends FragmentActivity
        implements DialogButtonListener, DialogItemListener, OnCancelListener, OnDismissListener { // NO_UCD (use default)
    static final String ACTION_SHARE = LogActionsActivity.class.getPackage().getName() + "_share";
    static final String ACTION_CLEAR = LogActionsActivity.class.getPackage().getName() + "_clear";

    private static final String TAG = Constants.TAG + LogActionsActivity.class.getSimpleName();
    private static final String PROGRESS_DIALOG_TAG = ProgressDialogFragment.class.getSimpleName();
    // True if the user interacted with a dialog other than to dismiss it.
    // IE: they clicked "ok" or selected an item from the list.
    private boolean mUserInput = false;

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        String action = getIntent().getAction();
        if (ACTION_SHARE.equals(action)) {
            DialogFragmentFactory.showChoiceDialog(this, getString(R.string.export_choice_title),
                    getResources().getStringArray(R.array.export_choices), -1, R.id.action_share);
        } else if (ACTION_CLEAR.equals(action)) {
            DialogFragmentFactory.showConfirmDialog(this, getString(R.string.action_clear),
                    getString(R.string.confirm_logs_clear), R.id.action_clear, null);
        } else {
            Log.w(TAG, "Activity created without a known action.  Action=" + action);
            finish();
        }
    }

    /**
     * Prompt a user for the field they want to export to KML, then do the export.
     */
    private void shareKml() {
        Log.v(TAG, "shareKml");

        PreferenceDialog.showKMLExportColumnChoiceDialog(this,
                new PreferenceDialog.PreferenceChoiceDialogListener() {

                    @Override
                    public void onPreferenceValueSelected(String value) {
                        try {
                            KMLExport kmlExport = new KMLExport(LogActionsActivity.this, mExportProgressListener,
                                    value);
                            shareFile(kmlExport);
                        } catch (FileNotFoundException e) {
                            Log.w(TAG, "Error sharing file: " + e.getMessage(), e);
                        }
                    }

                    @Override
                    public void onCancel() {
                        setResult(RESULT_CANCELED);
                        finish();
                    }
                });
    }

    /**
     * Run the given file export, then bring up the chooser intent to share the exported file.
     */
    private void shareFile(final FileExport fileExport) {
        Log.v(TAG, "shareFile " + fileExport);
        // Use a horizontal progress bar style if we can show progress of the export.
        String dialogMessage = getString(R.string.export_progress_preparing_export);
        int dialogStyle = fileExport != null ? ProgressDialog.STYLE_HORIZONTAL : ProgressDialog.STYLE_SPINNER;
        DialogFragmentFactory.showProgressDialog(this, dialogMessage, dialogStyle, PROGRESS_DIALOG_TAG);

        AsyncTask<Void, Void, File> asyncTask = new AsyncTask<Void, Void, File>() {

            @Override
            protected File doInBackground(Void... params) {
                File file = null;
                if (fileExport != null) {
                    if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
                        return null;
                    try {
                        // Export the file in the background.
                        file = fileExport.export();
                    } catch (Throwable t) {
                        Log.e(TAG, "Error exporting file " + fileExport + ": " + t.getMessage(), t);
                    }
                    if (file == null)
                        return null;
                }

                String reportSummary = SummaryExport.getSummary(LogActionsActivity.this);
                // Bring up the chooser to share the file.
                Intent sendIntent = new Intent();
                sendIntent.setAction(Intent.ACTION_SEND);
                sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.export_subject_send_log));

                String dateRange = SummaryExport.getDataCollectionDateRange(LogActionsActivity.this);

                String messageBody = getString(R.string.export_message_text, dateRange);
                if (file != null) {
                    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file.getAbsolutePath()));
                    sendIntent.setType("message/rfc822");
                    messageBody += getString(R.string.export_message_text_file_attached);
                } else {
                    sendIntent.setType("text/plain");
                }
                messageBody += reportSummary;
                sendIntent.putExtra(Intent.EXTRA_TEXT, messageBody);

                startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.action_share)));
                return file;
            }

            @Override
            protected void onPostExecute(File result) {
                super.onPostExecute(result);
                DialogFragment fragment = (DialogFragment) getSupportFragmentManager()
                        .findFragmentByTag(PROGRESS_DIALOG_TAG);
                if (fragment != null)
                    fragment.dismissAllowingStateLoss();
                // Show a toast if we failed to export a file.
                if (fileExport != null && result == null)
                    Toast.makeText(LogActionsActivity.this, R.string.export_error_sdcard_unmounted,
                            Toast.LENGTH_LONG).show();
                finish();
            }

        };
        asyncTask.execute();
    }

    private final FileExport.ExportProgressListener mExportProgressListener = new FileExport.ExportProgressListener() {

        @Override
        public void onExportProgress(final int progress, final int max) {
            Log.v(TAG, "onRowExported: " + progress + "/" + max);
            runOnUiThread(new Runnable() {

                @Override
                public void run() {

                    ProgressDialogFragment fragment = (ProgressDialogFragment) getSupportFragmentManager()
                            .findFragmentByTag(PROGRESS_DIALOG_TAG);
                    if (fragment != null) {
                        fragment.setProgress(progress, max);
                    }
                }
            });
        }
    };

    @Override
    public void onOkClicked(int actionId, Bundle extras) {
        Log.v(TAG, "onOkClicked, actionId = " + actionId);
        mUserInput = true;
        // The user confirmed to clear the logs.
        if (actionId == R.id.action_clear) {
            Log.v(TAG, "Clicked ok to clear log");
            DialogFragmentFactory.showProgressDialog(LogActionsActivity.this,
                    getString(R.string.progress_dialog_message), ProgressDialog.STYLE_SPINNER, PROGRESS_DIALOG_TAG);
            AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {

                @Override
                protected Void doInBackground(Void... params) {
                    Log.v(TAG, "clear:doInBackground");
                    getContentResolver().delete(NetMonColumns.CONTENT_URI, null, null);
                    return null;
                }

                @Override
                protected void onPostExecute(Void result) {
                    // Once the DB is deleted, reload the WebView.
                    Log.v(TAG, "clear:onPostExecute");
                    Toast.makeText(LogActionsActivity.this, R.string.success_logs_clear, Toast.LENGTH_LONG).show();
                    setResult(RESULT_OK);
                    finish();
                }
            };
            asyncTask.execute();
        }
    }

    @Override
    public void onItemSelected(int actionId, CharSequence[] choices, int which) {
        Log.v(TAG, "onItemSelected: actionId =  " + actionId + ", choices = " + Arrays.toString(choices)
                + ", which = " + which);
        mUserInput = true;
        // The user picked a file format to export.
        if (actionId == R.id.action_share) {

            String[] exportChoices = getResources().getStringArray(R.array.export_choices);
            FileExport fileExport = null;
            try {
                if (getString(R.string.export_choice_csv).equals(exportChoices[which])) {
                    fileExport = new CSVExport(LogActionsActivity.this, mExportProgressListener);
                } else if (getString(R.string.export_choice_html).equals(exportChoices[which])) {
                    fileExport = new HTMLExport(LogActionsActivity.this, true, mExportProgressListener);
                } else if (getString(R.string.export_choice_kml).equals(exportChoices[which])) {
                    // The KML export requires a second dialog before we can share, so we return here.
                    shareKml();
                    return;
                } else if (getString(R.string.export_choice_excel).equals(exportChoices[which])) {
                    fileExport = new ExcelExport(LogActionsActivity.this, mExportProgressListener);
                } else if (getString(R.string.export_choice_db).equals(exportChoices[which])) {
                    fileExport = new DBExport(LogActionsActivity.this, mExportProgressListener);
                } else {
                    // Text summary only
                }
                shareFile(fileExport);
            } catch (IOException e) {
                Log.w(TAG, "Error sharing file: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public void onCancelClicked(int actionId, Bundle extras) {
        Log.v(TAG, "onCancelClicked, actionId = " + actionId);
        if (actionId == R.id.action_clear || actionId == R.id.action_share)
            dismiss();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        Log.v(TAG, "onDismiss");
        if (mUserInput) {
            // Ignore, the dialog was dismissed because the user tapped ok on the dialog or selected an item from the list in the dialog.
        } else {
            dismiss();
        }
    }

    /**
     * Listener to finish this activity with a canceled result when the user presses back on a dialog.
     */
    @Override
    public void onCancel(DialogInterface dialog) {
        Log.v(TAG, "onCancel");
        dismiss();
    }

    private void dismiss() {
        Log.v(TAG, "dismiss");
        setResult(RESULT_CANCELED);
        finish();
    }
}