Android Open Source - utexas-utilities Data Usage Activity






From Project

Back to project page utexas-utilities.

License

The source code is released under:

Apache License

If you think the Android project utexas-utilities listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.nasageek.utexasutilities.activities;
//from   ww  w. ja v  a 2  s.co  m
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.MenuItem;
import com.androidplot.xy.BarFormatter;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYSeries;
import com.androidplot.xy.XYStepMode;
import com.nasageek.utexasutilities.AsyncTask;
import com.nasageek.utexasutilities.AuthCookie;
import com.nasageek.utexasutilities.R;
import com.nasageek.utexasutilities.UTilitiesApplication;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.acra.ACRA;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.nasageek.utexasutilities.UTilitiesApplication.PNA_AUTH_COOKIE_KEY;

public class DataUsageActivity extends SherlockActivity implements OnTouchListener {

    private OkHttpClient httpclient;
    private Float[] downdata, totaldata;
    private Long[] labels;
    private XYPlot graph;
    private ProgressBar mProgress;
    private TextView dataUsedText;
    private TextView detv;
    private LinearLayout dell;
    private Button deb;
    private String usedText;
    private LinearLayout d_pb_ll;
    private ActionBar actionbar;

    private PointD minXY;
    private PointD maxXY;
    private double absMinX;
    private double absMaxX;
    private double minNoError;
    private double maxNoError;
    private double minDif;
    private double maxDif;

    private double percentused;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.data_layout);

        d_pb_ll = (LinearLayout) findViewById(R.id.data_progressbar_ll);
        dataUsedText = (TextView) findViewById(R.id.dataUsedText);
        mProgress = (ProgressBar) findViewById(R.id.percentDataUsed);
        dell = (LinearLayout) findViewById(R.id.data_error);
        detv = (TextView) findViewById(R.id.tv_failure);
        deb = (Button) findViewById(R.id.button_send_data);
        actionbar = getSupportActionBar();
        actionbar.setTitle("Data Usage");
        actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionbar.setHomeButtonEnabled(true);
        actionbar.setDisplayHomeAsUpEnabled(true);

        graph = (XYPlot) findViewById(R.id.mySimpleXYPlot);
        graph.setOnTouchListener(this);
        graph.setMarkupEnabled(false);

        labels = new Long[288];
        downdata = new Float[288];
        totaldata = new Float[288];

        httpclient = new OkHttpClient();

        new fetchDataTask(httpclient).execute();
        new fetchProgressTask(httpclient).execute();

    }

    // Definition of the touch states
    static final private int NONE = 0;
    static final private int ONE_FINGER_DRAG = 1;
    private int mode = NONE;

    private PointF firstFinger;
    private float lastScrolling;
    private float lastZooming;

    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: // Start gesture
                firstFinger = new PointF(event.getX(), event.getY());
                mode = ONE_FINGER_DRAG;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                // When the gesture ends, a thread is created to give inertia to
                // the scrolling and zoom
                final Timer t = new Timer();
                t.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        while (Math.abs(lastScrolling) > 1f || Math.abs(lastZooming - 1) > 1.01) {
                            lastScrolling *= .8; // speed of scrolling damping
                            scroll(lastScrolling);
                            lastZooming += (1 - lastZooming) * .2; // speed of
                                                                   // zooming
                                                                   // damping
                            zoom(lastZooming);
                            graph.redraw();
                        }
                    }
                }, 0);
                break;

            case MotionEvent.ACTION_MOVE:
                if (mode == ONE_FINGER_DRAG) {
                    final PointF oldFirstFinger = firstFinger;
                    firstFinger = new PointF(event.getX(), event.getY());
                    lastScrolling = oldFirstFinger.x - firstFinger.x;
                    scroll(lastScrolling);
                    lastZooming = (firstFinger.y - oldFirstFinger.y) / graph.getHeight();
                    if (lastZooming < 0) {
                        lastZooming = 1 / (1 - lastZooming);
                    } else {
                        lastZooming += 1;
                    }
                    zoom(lastZooming);

                    graph.redraw();

                }
                break;
        }
        return true;
    }

    private void zoom(float scale) {
        final double domainSpan = maxXY.x - minXY.x;
        final double domainMidPoint = maxXY.x - domainSpan / 2.0f;
        final double offset = domainSpan * scale / 2.0f;
        minXY.x = domainMidPoint - offset;
        maxXY.x = domainMidPoint + offset;
        checkBoundaries();
    }

    private void scroll(float pan) {
        final double domainSpan = maxXY.x - minXY.x;
        final double step = domainSpan / graph.getWidth();
        final double offset = pan * step;
        minXY.x += offset;
        maxXY.x += offset;

        if (minXY.x < absMinX) {
            minXY.x = absMinX;
            maxXY.x -= offset;// (absMinX-minXY.x);
        } else if (minXY.x > maxNoError) {
            minXY.x = maxNoError;
        }
        if (maxXY.x > absMaxX) {
            maxXY.x = absMaxX;// (maxXY.x-absMaxX);
            minXY.x -= offset;// (maxXY.x-absMaxX);
        } else if (maxXY.x < minNoError) {
            maxXY.x = minNoError;
        }
        if (maxXY.x - minXY.x < minDif) {
            maxXY.x = maxXY.x + (minDif - (maxXY.x - minXY.x));
        }

        graph.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.FIXED);
    }

    private void checkBoundaries() {
        // Make sure the proposed domain boundaries will not cause plotting
        // issues
        if (minXY.x < absMinX || ((Double) minXY.x).equals(Double.NaN)) {
            minXY.x = absMinX;
        } else if (minXY.x > maxNoError) {
            minXY.x = maxNoError;
        }
        if (maxXY.x > absMaxX || ((Double) maxXY.x).equals(Double.NaN)) {
            maxXY.x = absMaxX;
        } else if (maxXY.x < minNoError) {
            maxXY.x = minNoError;
        }
        if (maxXY.x - minXY.x < minDif) {
            maxXY.x = maxXY.x + (minDif - (maxXY.x - minXY.x));
        } else if (maxXY.x - minXY.x > maxDif) {
            maxXY.x = maxXY.x + (maxDif - (maxXY.x - minXY.x));
        }
        graph.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.FIXED);
    }

    private class fetchProgressTask extends AsyncTask<Object, Void, Void> {
        private OkHttpClient client;

        public fetchProgressTask(OkHttpClient client) {
            this.client = client;
        }

        @Override
        protected Void doInBackground(Object... params) {
            String reqUrl = "https://management.pna.utexas.edu/server/graph.cgi";
            Request request = new Request.Builder()
                    .url(reqUrl)
                    .build();
            String pagedata = "";

            try {
                Response response = client.newCall(request).execute();
                pagedata = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
                cancel(true);
                return null;
            }

            Pattern percentpattern = Pattern.compile("\\((.+?)%\\)");
            Matcher percentmatcher = percentpattern.matcher(pagedata);
            String found = "0.00";
            if (percentmatcher.find()) {
                found = percentmatcher.group(1);
            }
            percentused = Double.parseDouble(found);

            Pattern usedpattern = Pattern.compile("<b>(.*?)</b>");
            Matcher usedmatcher = usedpattern.matcher(pagedata);
            usedText = "UTilities could not find your % data usage";
            if (usedmatcher.find()) {
                usedText = usedmatcher.group(1);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void v) {
            dataUsedText.setText(usedText);
            mProgress.setProgress((int) (percentused * 10));
        }

        @Override
        protected void onCancelled() {
            dataUsedText.setText("UTilities could not fetch your % data usage");
        }
    }

    private class fetchDataTask extends AsyncTask<Object, Void, Character> {
        private OkHttpClient client;
        private String errorMsg;
        private Exception ex;
        private Boolean showButton = false;
        private String errorData;

        public fetchDataTask(OkHttpClient client) {
            this.client = client;
        }

        @Override
        protected Character doInBackground(Object... params) {
            AuthCookie pnaCookie = ((UTilitiesApplication) getApplication()).getAuthCookie(PNA_AUTH_COOKIE_KEY);
            Pattern authidpattern = Pattern.compile("(?<=%20)\\d+");
            Matcher authidmatcher = authidpattern.matcher(pnaCookie.getAuthCookieVal());
            String reqUrl;
            if (authidmatcher.find()) {
                reqUrl = "https://management.pna.utexas.edu/server/get-bw-graph-data.cgi?authid="
                                + authidmatcher.group();
            } else {
                cancel(true);
                errorMsg = "UTilities could not fetch your data usage";
                Log.d(DataUsageActivity.class.getSimpleName(), "No authid found");
                return ' ';
            }

            Request request = new Request.Builder()
                    .url(reqUrl)
                    .build();
            String pagedata = "";

            try {
                Response response = client.newCall(request).execute();
                pagedata = response.body().string();
            } catch (IOException e) {
                errorMsg = "UTilities could not fetch your data usage";
                e.printStackTrace();
                cancel(true);
                return ' ';
            }

            String[] lines = pagedata.split("\n");
            if (!lines[0].equals("Date,MB In,MB Out,MB Total")) {
                cancel(true);
                errorMsg = "UTilities could not fetch your data usage";
                return ' ';
            }
            Calendar date = Calendar.getInstance();

            // if there's more than a week of data, show just the last week,
            // otherwise show it all
            for (int i = lines.length >= 288 ? lines.length - 288 : 0, x = 0; i < lines.length; i++, x++) {
                String[] entry = lines[i].split(",");
                date.clear();
                try {
                    // TODO: this crashes sometimes on the [2] access, not sure
                    // why
                    date.set(Integer.parseInt(entry[0].split("/")[0]),
                            Integer.parseInt(entry[0].split("/")[1]) - 1,
                            Integer.parseInt(entry[0].split("/| ")[2]),
                            Integer.parseInt(entry[0].split(" |:")[1]),
                            Integer.parseInt(entry[0].split(" |:")[2]));
                } catch (NumberFormatException nfe) {
                    cancel(true);
                    errorMsg = "UTilities could not fetch your data usage";
                    nfe.printStackTrace();
                    return ' ';
                } catch (ArrayIndexOutOfBoundsException aibe) {
                    errorMsg = "UTilities could not parse your data usage";
                    ex = aibe;
                    StringBuilder data = new StringBuilder();
                    for (String line : lines) {
                        data.append(line).append("\n");
                    }
                    errorData = data.toString();
                    showButton = true;
                    aibe.printStackTrace();
                    cancel(true);
                    return ' ';
                }
                labels[x] = date.getTimeInMillis();
                downdata[x] = (Float.valueOf(entry[1]));

                // psh who needs updata when you can just overlay downdata on
                // top of totaldata?
                // updata[x]=(Float.valueOf(entry[2]));
                totaldata[x] = (Float.valueOf(entry[3]));
            }
            return ' ';
        }

        @Override
        protected void onPostExecute(Character result) {
            XYSeries series = new SimpleXYSeries(Arrays.asList(labels), Arrays.asList(downdata),
                    "Downloaded");
            XYSeries seriestotal = new SimpleXYSeries(Arrays.asList(labels),
                    Arrays.asList(totaldata), "Uploaded");

            BarFormatter downbarformatter = new BarFormatter(0xFF42D692, Color.BLACK);
            BarFormatter upbarformatter = new BarFormatter(0xFF388DFF, Color.BLACK);

            downbarformatter.getBorderPaint().setStrokeWidth(0);
            upbarformatter.getBorderPaint().setStrokeWidth(0);

            Paint gridpaint = new Paint();
            gridpaint.setColor(Color.DKGRAY);
            gridpaint.setAntiAlias(true);
            gridpaint.setStyle(Paint.Style.STROKE);

            graph.getGraphWidget().setDomainGridLinePaint(gridpaint);
            graph.getGraphWidget().setRangeGridLinePaint(gridpaint);
            graph.setTicksPerDomainLabel(4);

            graph.addSeries(seriestotal, upbarformatter);
            graph.addSeries(series, downbarformatter);

            graph.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1800000);
            graph.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 30);

            graph.calculateMinMaxVals();
            minXY = new PointD(graph.getCalculatedMinX().doubleValue(), graph.getCalculatedMinY()
                    .doubleValue()); // initial minimum data point
            absMinX = minXY.x; // absolute minimum data point
            // TODO: this crashes with a NPE sometimes. ??
            // absolute minimum value for the domain boundary maximum
            Number temp = series.getX(1);
            if (temp == null) {
                errorMsg = "There was an error fetching or displaying your data usage.";
                detv.setText(errorMsg);
                d_pb_ll.setVisibility(View.GONE);
                dell.setVisibility(View.VISIBLE);
                return;
            }
            minNoError = Math.round(temp.doubleValue() + 2);
            maxXY = new PointD(graph.getCalculatedMaxX().doubleValue(), graph.getCalculatedMaxY()
                    .doubleValue()); // initial maximum data point

            graph.setTicksPerRangeLabel(maxXY.y > 61 ? 2 : 1);

            absMaxX = maxXY.x; // absolute maximum data point
            // absolute maximum value for the domain boundary minimum
            maxNoError = (double) Math.round(series.getX(series.size() - 1).doubleValue()) - 2;
            minDif = 3000000;
            maxDif = 33000000;

            graph.setRangeUpperBoundary(maxXY.y > 31 ? maxXY.y : 31, BoundaryMode.FIXED);
            graph.setRangeLowerBoundary(0, BoundaryMode.FIXED);
            graph.setDomainUpperBoundary(maxXY.x, BoundaryMode.FIXED);
            graph.setDomainLowerBoundary(minXY.x, BoundaryMode.FIXED);
            checkBoundaries();

            graph.setDomainValueFormat(new TimeFormat());
            graph.redraw();
            graph.setVisibility(View.VISIBLE);
            d_pb_ll.setVisibility(View.GONE);

            Toast.makeText(DataUsageActivity.this, "Swipe up and down to zoom in and out",
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        protected void onCancelled() {
            detv.setText(errorMsg);
            deb.setText("Send anonymous information about your data usage to help improve UTilities.");
            deb.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (errorData != null && ex != null) {
                        SharedPreferences sp = PreferenceManager
                                .getDefaultSharedPreferences(DataUsageActivity.this
                                        .getBaseContext());
                        if (!sp.getBoolean("acra.enable", true)) {
                            ACRA.getErrorReporter().setEnabled(true);
                        }
                        ACRA.getErrorReporter().putCustomData("xmldata", errorData);
                        ACRA.getErrorReporter().handleException(ex);
                        ACRA.getErrorReporter().removeCustomData("xmldata");
                        if (!sp.getBoolean("acra.enable", true)) {
                            ACRA.getErrorReporter().setEnabled(false);
                        }
                        Toast.makeText(DataUsageActivity.this,
                                "Data is being sent, thanks for helping out!", Toast.LENGTH_SHORT)
                                .show();
                    } else {
                        Toast.makeText(DataUsageActivity.this,
                                "Couldn't send the course data for some reason :(",
                                Toast.LENGTH_SHORT).show();
                    }
                    v.setVisibility(View.INVISIBLE);
                }
            });
            d_pb_ll.setVisibility(View.GONE);
            dell.setVisibility(View.VISIBLE);
            if (showButton) {
                deb.setVisibility(View.VISIBLE);
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                // app icon in action bar clicked; go home
                super.onBackPressed();
                break;
        }
        return true;
    }

    private class TimeFormat extends Format {

        private static final long serialVersionUID = 1L;
        // create a simple date format that draws on the year portion of our
        // timestamp.
        // see
        // http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
        // for a full description of SimpleDateFormat.
        private SimpleDateFormat dateFormat = new SimpleDateFormat("E - HH:mm", Locale.US);

        @Override
        public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
            long timestamp = ((Number) obj).longValue();
            Date date = new Date(timestamp);
            return dateFormat.format(date, toAppendTo, pos);
        }

        @Override
        public Object parseObject(String source, ParsePosition pos) {
            return null;
        }
    }

    private class PointD {
        double x, y;

        public PointD(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
}




Java Source Code List

com.google.maps.android.ui.MyIconGenerator.java
com.mapsaurus.paneslayout.ActivityDelegate.java
com.mapsaurus.paneslayout.FragmentLauncher.java
com.mapsaurus.paneslayout.MenuItemWrapper.java
com.mapsaurus.paneslayout.MySlidingPaneLayout.java
com.mapsaurus.paneslayout.PanesActivity.java
com.mapsaurus.paneslayout.PanesLayout.java
com.mapsaurus.paneslayout.PanesSizer.java
com.mapsaurus.paneslayout.PhoneDelegate.java
com.mapsaurus.paneslayout.SimpleScrollView.java
com.mapsaurus.paneslayout.TabletDelegate.java
com.nasageek.utexasutilities.AsyncTask.java
com.nasageek.utexasutilities.AttachmentDownloadService.java
com.nasageek.utexasutilities.AuthCookie.java
com.nasageek.utexasutilities.BlackboardDashboardXmlParser.java
com.nasageek.utexasutilities.BuildingDatabase.java
com.nasageek.utexasutilities.BuildingProvider.java
com.nasageek.utexasutilities.BuildingSaxHandler.java
com.nasageek.utexasutilities.ChangeLog.java
com.nasageek.utexasutilities.ChangeableContextTask.java
com.nasageek.utexasutilities.CourseMapSaxHandler.java
com.nasageek.utexasutilities.FixedListPreference.java
com.nasageek.utexasutilities.LoginWebViewClient.java
com.nasageek.utexasutilities.MarkerManager.java
com.nasageek.utexasutilities.MyPair.java
com.nasageek.utexasutilities.MyScrollView.java
com.nasageek.utexasutilities.PlacemarkSaxHandler.java
com.nasageek.utexasutilities.PnaAuthCookie.java
com.nasageek.utexasutilities.RouteSaxHandler.java
com.nasageek.utexasutilities.SecurePreferences.java
com.nasageek.utexasutilities.TempLoginException.java
com.nasageek.utexasutilities.UTilitiesApplication.java
com.nasageek.utexasutilities.UtdAuthCookie.java
com.nasageek.utexasutilities.Utility.java
com.nasageek.utexasutilities.WrappedViewPager.java
com.nasageek.utexasutilities.WrappingSlidingDrawer.java
com.nasageek.utexasutilities.activities.AboutMeActivity.java
com.nasageek.utexasutilities.activities.BalanceActivity.java
com.nasageek.utexasutilities.activities.BlackboardPanesActivity.java
com.nasageek.utexasutilities.activities.CampusMapActivity.java
com.nasageek.utexasutilities.activities.DataUsageActivity.java
com.nasageek.utexasutilities.activities.LoginActivity.java
com.nasageek.utexasutilities.activities.MenuActivity.java
com.nasageek.utexasutilities.activities.NutritionInfoActivity.java
com.nasageek.utexasutilities.activities.Preferences.java
com.nasageek.utexasutilities.activities.ScheduleActivity.java
com.nasageek.utexasutilities.activities.UTilitiesActivity.java
com.nasageek.utexasutilities.adapters.BBClassAdapter.java
com.nasageek.utexasutilities.adapters.CourseMapAdapter.java
com.nasageek.utexasutilities.adapters.MultiPanePagerAdapter.java
com.nasageek.utexasutilities.adapters.MyFragmentPagerAdapter.java
com.nasageek.utexasutilities.adapters.ScheduleClassAdapter.java
com.nasageek.utexasutilities.adapters.TransactionAdapter.java
com.nasageek.utexasutilities.fragments.ActionModeFragment.java
com.nasageek.utexasutilities.fragments.BlackboardAnnouncementsFragment.java
com.nasageek.utexasutilities.fragments.BlackboardCourseListFragment.java
com.nasageek.utexasutilities.fragments.BlackboardCourseMapFragment.java
com.nasageek.utexasutilities.fragments.BlackboardDashboardFragment.java
com.nasageek.utexasutilities.fragments.BlackboardDownloadableItemFragment.java
com.nasageek.utexasutilities.fragments.BlackboardExternalItemFragment.java
com.nasageek.utexasutilities.fragments.BlackboardFragment.java
com.nasageek.utexasutilities.fragments.BlackboardGradesFragment.java
com.nasageek.utexasutilities.fragments.BlackboardPagerFragment.java
com.nasageek.utexasutilities.fragments.CourseScheduleFragment.java
com.nasageek.utexasutilities.fragments.DatePickerFragment.java
com.nasageek.utexasutilities.fragments.DoubleDatePickerDialogFragment.java
com.nasageek.utexasutilities.fragments.ExamScheduleFragment.java
com.nasageek.utexasutilities.fragments.MenuFragment.java
com.nasageek.utexasutilities.fragments.NutritionInfoFragment.java
com.nasageek.utexasutilities.fragments.PickCalendarDialogFragment.java
com.nasageek.utexasutilities.fragments.TransactionsFragment.java
com.nasageek.utexasutilities.model.BBClass.java
com.nasageek.utexasutilities.model.Building.java
com.nasageek.utexasutilities.model.Classtime.java
com.nasageek.utexasutilities.model.CourseMapItem.java
com.nasageek.utexasutilities.model.FeedItem.java
com.nasageek.utexasutilities.model.Placemark.java
com.nasageek.utexasutilities.model.Transaction.java
com.nasageek.utexasutilities.model.UTClass.java
com.viewpagerindicator.MyTabPageIndicator.java