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

Java tutorial

Introduction

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

Source

/*
 * This source is part of the
 *      _____  ___   ____
 *  __ / / _ \/ _ | / __/___  _______ _
 * / // / , _/ __ |/ _/_/ _ \/ __/ _ `/
 * \___/_/|_/_/ |_/_/ (_)___/_/  \_, /
 *                              /___/
 * repository.
 *
 * Copyright (C) 2013 Benoit 'BoD' Lubek (BoD@JRAF.org)
 * Copyright (C) 2013-2015 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 android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

import ca.rmen.android.networkmonitor.Constants;
import ca.rmen.android.networkmonitor.R;
import ca.rmen.android.networkmonitor.app.dbops.backend.export.HTMLExport;
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.prefs.FilterColumnActivity;
import ca.rmen.android.networkmonitor.app.prefs.NetMonPreferences;
import ca.rmen.android.networkmonitor.app.prefs.PreferenceFragmentActivity;
import ca.rmen.android.networkmonitor.app.prefs.SelectFieldsActivity;
import ca.rmen.android.networkmonitor.app.prefs.SortPreferences;
import ca.rmen.android.networkmonitor.app.prefs.SortPreferences.SortOrder;
import ca.rmen.android.networkmonitor.util.Log;

public class LogActivity extends AppCompatActivity implements DialogButtonListener {
    private static final String TAG = Constants.TAG + LogActivity.class.getSimpleName();
    private WebView mWebView;
    private Dialog mDialog;
    private Menu mMenu;
    private static final int REQUEST_CODE_CLEAR = 1;
    private static final int REQUEST_CODE_SELECT_FIELDS = 2;
    private static final int REQUEST_CODE_FILTER_COLUMN = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.v(TAG, "onCreate " + savedInstanceState);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.log);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        loadHTMLFile();
    }

    @Override
    protected void onPause() {
        Log.v(TAG, "onPause");
        if (mDialog != null)
            mDialog.dismiss();
        super.onPause();
        PreferenceManager.getDefaultSharedPreferences(this)
                .unregisterOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
    }

    @Override
    protected void onResume() {
        Log.v(TAG, "onResume");
        super.onResume();
        if (mDialog != null)
            mDialog.show();
        PreferenceManager.getDefaultSharedPreferences(this)
                .registerOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
    }

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

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // Only show the menu item to clear filters if we have filters.
        menu.findItem(R.id.action_reset_filters).setVisible(NetMonPreferences.getInstance(this).hasColumnFilters());
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        case R.id.action_share:
            Intent intentShare = new Intent(PreferenceFragmentActivity.ACTION_SHARE);
            startActivity(intentShare);
            return true;
        case R.id.action_refresh:
            loadHTMLFile();
            return true;
        case R.id.action_clear:
            Intent intentClear = new Intent(PreferenceFragmentActivity.ACTION_CLEAR);
            startActivityForResult(intentClear, REQUEST_CODE_CLEAR);
            return true;
        case R.id.action_select_fields:
            Intent intentSelectFields = new Intent(this, SelectFieldsActivity.class);
            startActivityForResult(intentSelectFields, REQUEST_CODE_SELECT_FIELDS);
            return true;
        case R.id.action_filter:
            mDialog = PreferenceDialog.showFilterRecordCountChoiceDialog(this, mPreferenceChoiceDialogListener);
            return true;
        case R.id.action_cell_id_format:
            mDialog = PreferenceDialog.showCellIdFormatChoiceDialog(this, mPreferenceChoiceDialogListener);
            return true;
        case R.id.action_reset_filters:
            DialogFragmentFactory.showConfirmDialog(this, getString(R.string.clear_filters_confirm_dialog_title),
                    getString(R.string.clear_filters_confirm_dialog_message), R.id.action_reset_filters, null);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Read the data from the DB, export it to an HTML file, and load the HTML file in the WebView.
     */
    private void loadHTMLFile() {
        Log.v(TAG, "loadHTMLFile");
        final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
        progressBar.setVisibility(View.VISIBLE);
        startRefreshIconAnimation();
        AsyncTask<Void, Void, File> asyncTask = new AsyncTask<Void, Void, File>() {

            @Override
            protected File doInBackground(Void... params) {
                Log.v(TAG, "loadHTMLFile:doInBackground");
                // Export the DB to the HTML file.
                HTMLExport htmlExport = new HTMLExport(LogActivity.this, false);
                int recordCount = NetMonPreferences.getInstance(LogActivity.this).getFilterRecordCount();
                return htmlExport.export(recordCount, null);
            }

            @SuppressLint("SetJavaScriptEnabled")
            @Override
            protected void onPostExecute(File result) {
                Log.v(TAG, "loadHTMLFile:onPostExecute, result=" + result);
                if (isFinishing()) {
                    Log.v(TAG, "finishing, ignoring loadHTMLFile result");
                    return;
                }
                if (result == null) {
                    Toast.makeText(LogActivity.this, R.string.error_reading_log, Toast.LENGTH_LONG).show();
                    return;
                }
                // Load the exported HTML file into the WebView.
                mWebView = (WebView) findViewById(R.id.web_view);
                // Save our current horizontal scroll position so we can keep our
                // horizontal position after reloading the page.
                final int oldScrollX = mWebView.getScrollX();
                mWebView.getSettings().setUseWideViewPort(true);
                mWebView.getSettings().setBuiltInZoomControls(true);
                mWebView.getSettings().setJavaScriptEnabled(true);
                mWebView.loadUrl("file://" + result.getAbsolutePath());
                mWebView.setWebViewClient(new WebViewClient() {

                    @Override
                    public void onPageStarted(WebView view, String url, Bitmap favicon) {
                        super.onPageStarted(view, url, favicon);
                        Log.v(TAG, "onPageStarted");
                        // Javascript hack to scroll back to our old X position.
                        // http://stackoverflow.com/questions/6855715/maintain-webview-content-scroll-position-on-orientation-change
                        if (oldScrollX > 0) {
                            String jsScrollX = "javascript:window:scrollTo(" + oldScrollX
                                    + " / window.devicePixelRatio,0);";
                            view.loadUrl(jsScrollX);
                        }
                    }

                    @Override
                    public void onPageFinished(WebView view, String url) {
                        super.onPageFinished(view, url);
                        progressBar.setVisibility(View.GONE);
                        stopRefreshIconAnimation();
                    }

                    @Override
                    public boolean shouldOverrideUrlLoading(WebView view, String url) {
                        Log.v(TAG, "url: " + url);
                        // If the user clicked on one of the column names, let's update
                        // the sorting preference (column name, ascending or descending order).
                        if (url.startsWith(HTMLExport.URL_SORT)) {
                            NetMonPreferences prefs = NetMonPreferences.getInstance(LogActivity.this);
                            SortPreferences oldSortPreferences = prefs.getSortPreferences();
                            // The new column used for sorting will be the one the user tapped on.
                            String newSortColumnName = url.substring(HTMLExport.URL_SORT.length());
                            SortOrder newSortOrder = oldSortPreferences.sortOrder;
                            // If the user clicked on the column which is already used for sorting,
                            // toggle the sort order between ascending and descending.
                            if (newSortColumnName.equals(oldSortPreferences.sortColumnName)) {
                                if (oldSortPreferences.sortOrder == SortOrder.DESC)
                                    newSortOrder = SortOrder.ASC;
                                else
                                    newSortOrder = SortOrder.DESC;
                            }
                            // Update the sorting preferences (our shared preference change listener will be notified
                            // and reload the page).
                            prefs.setSortPreferences(new SortPreferences(newSortColumnName, newSortOrder));
                            return true;
                        }
                        // If the user clicked on the filter icon, start the filter activity for this column.
                        else if (url.startsWith(HTMLExport.URL_FILTER)) {
                            Intent intent = new Intent(LogActivity.this, FilterColumnActivity.class);
                            String columnName = url.substring(HTMLExport.URL_FILTER.length());
                            intent.putExtra(FilterColumnActivity.EXTRA_COLUMN_NAME, columnName);
                            startActivityForResult(intent, REQUEST_CODE_FILTER_COLUMN);
                            return true;
                        } else {
                            return super.shouldOverrideUrlLoading(view, url);
                        }
                    }
                });
            }
        };
        asyncTask.execute();
    }

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (mWebView != null) {
            if (Build.VERSION.SDK_INT >= 11)
                mWebView.getSettings().setDisplayZoomControls(false);
            mWebView.removeAllViews();
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.v(TAG, "onActivityResult: requestCode = " + requestCode + ", resultCode = " + resultCode + ", data  "
                + data);
        super.onActivityResult(requestCode, resultCode, data);
        if ((requestCode == REQUEST_CODE_CLEAR || requestCode == REQUEST_CODE_SELECT_FIELDS
                || requestCode == REQUEST_CODE_FILTER_COLUMN) && resultCode == RESULT_OK)
            loadHTMLFile();
    }

    /**
     * Reload the page when the user accepts a preference choice dialog.
     */
    private final PreferenceDialog.PreferenceChoiceDialogListener mPreferenceChoiceDialogListener = new PreferenceDialog.PreferenceChoiceDialogListener() {

        @Override
        public void onPreferenceValueSelected(final String value) {
            loadHTMLFile();
        }

        @Override
        public void onCancel() {
        }
    };

    /**
     * Refresh the screen when certain shared preferences change.
     */
    private final OnSharedPreferenceChangeListener mSharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            if (key.equals(NetMonPreferences.PREF_SORT_COLUMN_NAME)
                    || key.equals(NetMonPreferences.PREF_SORT_ORDER))
                loadHTMLFile();
        }
    };

    @Override
    public void onOkClicked(int actionId, Bundle extras) {
        // The user confirmed to clear the logs.  Let's do that and refresh the screen.
        if (actionId == R.id.action_reset_filters) {
            NetMonPreferences.getInstance(this).resetColumnFilters();
            loadHTMLFile();
        }
    }

    @Override
    public void onCancelClicked(int actionId, Bundle extras) {
    }

    private void startRefreshIconAnimation() {
        Log.v(TAG, "startRefreshIconAnimation");
        if (mMenu == null)
            return; // This is null when we first enter the activity and the page loads.
        MenuItem menuItemRefresh = mMenu.findItem(R.id.action_refresh);
        if (menuItemRefresh == null)
            return;
        View refreshIcon = View.inflate(this, R.layout.refresh_icon, null);
        Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotate);
        rotation.setRepeatCount(Animation.INFINITE);
        refreshIcon.startAnimation(rotation);
        MenuItemCompat.setActionView(menuItemRefresh, refreshIcon);
    }

    private void stopRefreshIconAnimation() {
        Log.v(TAG, "stopRefreshIconAnimation");
        if (mMenu == null)
            return;
        MenuItem menuItemRefresh = mMenu.findItem(R.id.action_refresh);
        if (menuItemRefresh == null)
            return;
        View refreshIcon = MenuItemCompat.getActionView(menuItemRefresh);
        if (refreshIcon != null) {
            refreshIcon.clearAnimation();
            MenuItemCompat.setActionView(menuItemRefresh, null);
        }
    }

}