Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package cz.master.hope.Fragments;
- import android.app.usage.UsageStatsManager;
- import android.content.Context;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.support.v4.content.ContextCompat;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ImageButton;
- import android.widget.ImageView;
- import android.widget.TextView;
- import com.github.mikephil.charting.animation.Easing;
- import com.github.mikephil.charting.charts.BarChart;
- import com.github.mikephil.charting.charts.PieChart;
- import com.github.mikephil.charting.components.Legend;
- import com.github.mikephil.charting.components.XAxis;
- import com.github.mikephil.charting.components.YAxis;
- import com.github.mikephil.charting.data.BarData;
- import com.github.mikephil.charting.data.BarDataSet;
- import com.github.mikephil.charting.data.BarEntry;
- import com.github.mikephil.charting.data.Entry;
- import com.github.mikephil.charting.data.PieData;
- import com.github.mikephil.charting.data.PieDataSet;
- import com.github.mikephil.charting.highlight.Highlight;
- import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
- import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
- import org.joda.time.DateTime;
- import java.text.DecimalFormat;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import cz.master.hope.AppUsageAndEvents.AppEvents;
- import cz.master.hope.AppUsageAndEvents.AppRunDuration;
- import cz.master.hope.AppUsageAndEvents.AppUsage;
- import cz.master.hope.R;
- import cz.master.hope.Utilities.ColorPalette;
- import cz.master.hope.Utilities.SharedPrefsAccess;
- import cz.master.hope.Utilities.TimeSpan;
- import static cz.master.hope.Utilities.DateFormator.formatAppUsageTime;
- import static cz.master.hope.Utilities.DateFormator.milisToDateString;
- /**
- * Fragment activity used for displaying users mobile activity.
- */
- public class MobileActivitiesFragment extends Fragment implements OnChartValueSelectedListener {
- /* Context */
- Context context;
- /* Constants */
- public final static int INIT = 0;
- public final static int ANIMATION_LENGTH = 1500;
- public final static float PIE_CHART_TEXT_SIZE = 13;
- public final static float PIE_CHART_HOLE_RADIUS = 65;
- public final static float PIE_CHART_TRANSPARENT_BORDER = 5;
- private static final String COLOR_PALETTE_KEY = "color_palette_item_";
- private static final String COLOR_PALETTE_INDEX = "color_palette_index" ;
- private static final String USAGE_STATS_NOT_PRESENT = "usage_stats_not_present";
- /* Highlighted pie chart part */
- private int highlightedPiePart = INIT;
- /* Shared preferences keys */
- public final static String SP_KEY_TIME_SPAN = "shared_preferences_key_time_span_mobile_activities";
- /* Time span */
- TimeSpan timeSpan = TimeSpan.TODAY;
- /* GUI elements */
- private PieChart pieChart;
- private BarChart barChart;
- private ImageView ivAppIcon;
- private TextView tvAppName;
- private TextView tvUsedTime;
- private TextView tvLastTimeUsed;
- private TextView tvTimeSpan;
- private ImageButton ibTimeSpanMinus;
- private ImageButton ibTimeSpanPlus;
- /* Package name to color hash map */
- private List<Integer> appColorPalette;
- /* Pie chart values */
- private ArrayList<Entry> pieChartYValues;
- private ArrayList<String> pieChartXValues;
- private PieDataSet pieDataSet;
- private List<AppUsage> usageStats;
- /* Bar chart values */
- private ArrayList<BarEntry> barChartYValues;
- private ArrayList<String> barChartXValues;
- private BarDataSet barDataSet;
- /**
- * Lifecycle of fragment.
- */
- /**
- * Refresh fragment. This method is called from parent activity.
- */
- public void refresh() {
- /* Refresh pie chart */
- updatePieChart();
- /* Refresh bar chart */
- updateBarChart();
- }
- /**
- * Required empty public constructor
- */
- public MobileActivitiesFragment() {}
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- context = getContext();
- /* Get last selected time span from shared preferences */
- String timeSpanString = SharedPrefsAccess.load(context, SP_KEY_TIME_SPAN);
- timeSpan = TimeSpan.getType(timeSpanString,context);
- }
- @Override
- public void onPause() {
- super.onPause();
- /* Store time span to shared preferences */
- SharedPrefsAccess.save(context, SP_KEY_TIME_SPAN, TimeSpan.getString(timeSpan, context));
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- /* Inflate the layout for this fragment */
- View fragmentView = inflater.inflate(R.layout.mobile_activites_fragment_layout, container, false);
- if (!SharedPrefsAccess.loadBool(context,USAGE_STATS_NOT_PRESENT)) {
- /* Setup GUI */
- setupGUI(fragmentView);
- /* Create bars */
- createPieChart();
- createBarChart();
- /* Change time span */
- //timeSpanPanel();
- }
- /* Inflate the layout for this fragment */
- return fragmentView;
- }
- /**
- * Connect to all GUI elements.
- */
- public void setupGUI(View fragmentView) {
- pieChart = (PieChart) fragmentView.findViewById(R.id.mobile_activites_fragment_pieChart);
- barChart = (BarChart) fragmentView.findViewById(R.id.mobile_activites_fragment_barChart);
- ivAppIcon = (ImageView) fragmentView.findViewById(R.id.mobile_activites_fragment_app_detail_image);
- tvAppName = (TextView) fragmentView.findViewById(R.id.mobile_activites_fragment_app_detail_name);
- tvUsedTime = (TextView) fragmentView.findViewById(R.id.mobile_activites_fragment_app_detail_time);
- tvLastTimeUsed = (TextView) fragmentView.findViewById(R.id.mobile_activites_fragment_app_detail_last_used);
- //tvTimeSpan = (TextView) fragmentView.findViewById(R.id.change_time_span_text);
- //ibTimeSpanMinus = (ImageButton) fragmentView.findViewById(R.id.change_time_span_minus);
- //ibTimeSpanPlus = (ImageButton) fragmentView.findViewById(R.id.change_time_span_plus);
- /* Set up listeners */
- pieChart.setOnChartValueSelectedListener(this);
- }
- /**
- * Pie chart.
- */
- /**
- * Initialize and configure pie chart. Also set data to it.
- */
- public void createPieChart() {
- configurePieChart();
- getPieChartData();
- pieChartSetHighlight(highlightedPiePart);
- pieChartOnHighlightChange(highlightedPiePart);
- }
- /**
- * Update pie chart.
- */
- public void updatePieChart() {
- getPieChartData();
- pieChartSetHighlight(highlightedPiePart);
- pieChartOnHighlightChange(highlightedPiePart);
- /* Run animation again */
- pieChart.animateY(ANIMATION_LENGTH, Easing.EasingOption.Linear);
- }
- /**
- * Collect data for pie chart.
- */
- public void getPieChartData() {
- /* Get app usage */
- usageStats = getPieChartSourceData();
- pieChartYValues = new ArrayList<>();
- pieChartXValues = new ArrayList<>();
- /* Get app usage data and percentage */
- float[] usagePercentage = AppUsage.countAppUsagePercentage(usageStats);
- for (int i = 0; i < usagePercentage.length; i++) {
- pieChartYValues.add(new Entry(usagePercentage[i], i));
- pieChartXValues.add(AppUsage.getAppName(usageStats.get(i).getPackageName(), context));
- }
- /* Init colors */
- initAppColorPalette();
- /* Create dataset */
- pieDataSet = new PieDataSet(pieChartYValues, "");
- pieDataSet.setDrawValues(false);
- pieDataSet.setColors(appColorPalette);
- pieChart.setData(new PieData(pieChartXValues, pieDataSet));
- }
- /**
- * Collect data according to selected time span.
- */
- public List<AppUsage> getPieChartSourceData() {
- switch (timeSpan) {
- case TODAY:
- return AppUsage.getAppUsageTodayFiltered(context);
- case LAST_WEEK:
- return AppUsage.getAppUsage(context, UsageStatsManager.INTERVAL_WEEKLY);
- case LAST_MONTH:
- return AppUsage.getAppUsage(context, UsageStatsManager.INTERVAL_MONTHLY);
- case LAST_YEAR:
- return AppUsage.getAppUsage(context, UsageStatsManager.INTERVAL_YEARLY);
- }
- return AppUsage.getAppUsage(context, UsageStatsManager.INTERVAL_DAILY);
- }
- /**
- * Configure pie chart settings.
- */
- public void configurePieChart() {
- pieChart.setDrawSliceText(false);
- pieChart.animateY(ANIMATION_LENGTH, Easing.EasingOption.Linear);
- pieChart.setDrawCenterText(true);
- pieChart.setCenterTextSize(PIE_CHART_TEXT_SIZE);
- pieChart.setHoleRadius(PIE_CHART_HOLE_RADIUS);
- pieChart.setTransparentCircleRadius(PIE_CHART_HOLE_RADIUS + PIE_CHART_TRANSPARENT_BORDER);
- /* Setup legend and description */
- configurePieChartLegend();
- pieChart.setDescription("");
- }
- /**
- * Configure pie chart legend.
- */
- public void configurePieChartLegend() {
- Legend legend = pieChart.getLegend();
- /* Display legend */
- legend.setEnabled(true);
- /* If enabled, the content of the legend will not clip outside the charts bounds,
- * but instead create a new line. Please note that this reduces performance
- * and is only available for legends below the chart.
- */
- legend.setWordWrapEnabled(true);
- /* Center legend */
- legend.setPosition(Legend.LegendPosition.BELOW_CHART_LEFT);
- }
- /**
- * Listen to click on PieChart element.
- */
- @Override
- public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
- highlightedPiePart = e.getXIndex();
- pieChartOnHighlightChange(e.getXIndex());
- }
- /**
- * Listen to unselected on PieChart element.
- */
- @Override
- public void onNothingSelected() {
- pieChartSetHighlight(INIT);
- pieChartOnHighlightChange(INIT);
- }
- /**
- * Highlight pie chart element with given index.
- */
- public void pieChartSetHighlight(int index) {
- Highlight h = new Highlight(index, INIT);
- pieChart.highlightValues(new Highlight[]{h});
- }
- /**
- * React to Pie chart highlight change.
- * - Display selected app in middle of pie chart.
- * - Change information in detail information bar.
- */
- public void pieChartOnHighlightChange(int index) {
- setPieChartMiddleText(index);
- setInfoPanelData(index);
- }
- /**
- * Display selected app in middle of pie chart.
- */
- public void setPieChartMiddleText(int index) {
- String appName;
- /* Get activity name */
- try {
- appName = pieChartXValues.get(index);
- /* There is possibility pie chart is gonna change on refresh in a way that it has less
- items.*/
- } catch (IndexOutOfBoundsException e) {
- pieChartOnHighlightChange(INIT);
- return;
- }
- /* Format percentage */
- DecimalFormat df = new DecimalFormat("0.0");
- String percentage = df.format(pieChartYValues.get(index).getVal());
- /* Text color change */
- pieChart.setCenterTextColor(pieDataSet.getColor(index));
- pieChart.setCenterText(appName + " " + percentage + "%");
- }
- /**
- * Set all data information about app run and display it on info panel.
- */
- public void setInfoPanelData(int index) {
- /* Others have special info panel configuration */
- if (pieChartXValues.get(index).equals("OTHERS")) {
- setInfoPanelOthers();
- return;
- }
- String packageName = usageStats.get(index).getPackageName();
- String appName = pieChartXValues.get(index);
- String usedTime = formatAppUsageTime(usageStats.get(index).getTotalTimeInForeground());
- String lastTimeUsed = milisToDateString(usageStats.get(index).getLastTimeUsed(),context);
- ivAppIcon.setImageDrawable(AppUsage.getAppIcon(context, packageName));
- tvAppName.setText(appName);
- tvUsedTime.setText(usedTime);
- tvLastTimeUsed.setText(lastTimeUsed);
- /* Change value colors */
- tvUsedTime.setTextColor(pieDataSet.getColor(index));
- tvLastTimeUsed.setTextColor(pieDataSet.getColor(index));
- }
- /**
- * Set all data information about Others app run and display it on info panel.
- */
- public void setInfoPanelOthers() {
- int index = usageStats.size() - 1;
- String usedTime = formatAppUsageTime(usageStats.get(index).getTotalTimeInForeground());
- String lastTimeUsed = milisToDateString(usageStats.get(index).getLastTimeUsed(),context);
- ivAppIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ideas_icon));
- tvAppName.setText(getString(R.string.otherApps));
- tvUsedTime.setText(usedTime);
- tvLastTimeUsed.setText(lastTimeUsed);
- /* Change value colors */
- tvUsedTime.setTextColor(pieDataSet.getColor(index));
- tvLastTimeUsed.setTextColor(pieDataSet.getColor(index));
- }
- /**
- * Bar chart.
- */
- /**
- * Initialize and configure bar chart. Also set data to it.
- */
- public void createBarChart() {
- configureBarChart();
- getBarChartData();
- barChartSetViewCenter();
- }
- /**
- * Update bar chart.
- */
- public void updateBarChart() {
- getBarChartData();
- barChartSetViewCenter();
- /* Run animation again */
- barChart.animateY(ANIMATION_LENGTH, Easing.EasingOption.Linear);
- }
- /**
- * Configure bar chart settings.
- */
- public void configureBarChart() {
- /* Basic settings */
- barChart.setPinchZoom(false);
- barChart.setDrawGridBackground(false);
- barChart.setDrawBarShadow(false);
- barChart.setDrawValueAboveBar(false);
- barChart.setDrawBorders(false);
- /* Get rid of all axis lines */
- barChart.getAxisLeft().setDrawGridLines(false);
- barChart.getAxisRight().setDrawGridLines(false);
- barChart.getXAxis().setDrawAxisLine(false);
- barChart.getXAxis().setDrawGridLines(false);
- barChart.getAxisLeft().setDrawAxisLine(false);
- barChart.getAxisRight().setDrawAxisLine(false);
- barChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM_INSIDE);
- /* Animation */
- barChart.animateY(ANIMATION_LENGTH, Easing.EasingOption.Linear);
- /* Hide all descriptions */
- barChart.setDescription("");
- barChart.getAxisLeft().setDrawLabels(false);
- barChart.getAxisRight().setDrawLabels(false);
- barChart.getLegend().setEnabled(false);
- /* Set zoom */
- barChart.setScaleMinima(3, 1);
- barChart.setDoubleTapToZoomEnabled(false);
- /* No highlighting */
- barChart.setHighlightPerDragEnabled(false);
- barChart.setHighlightPerTapEnabled(true);
- /* Get rid of margins */
- barChart.setViewPortOffsets(4f, 4f, 4f, 4f);
- }
- /**
- * Collect data for bar chart.
- */
- public void getBarChartData() {
- /* Init lists */
- barChartXValues = new ArrayList<>();
- barChartYValues = new ArrayList<>();
- /* Dataset */
- createBarChartDataset();
- ArrayList<IBarDataSet> dataSets = new ArrayList<>();
- dataSets.add(barDataSet);
- BarData data = new BarData(barChartXValues, dataSets);
- barChart.setData(data);
- barChart.invalidate();
- }
- /**
- * Create bar chart item dataset.
- */
- public void createBarChartDataset() {
- /* Get current time */
- DateTime now = new DateTime();
- /* Get all events tha happened in last 24 hours */
- List<List<AppRunDuration>> appsRunDuration = AppEvents.getAppsRunDurationDividedByHours
- (usageStats,context, now.withTimeAtStartOfDay().getMillis());
- /* Displaying 24 hours */
- for (int i = 0; i < 24; i++)
- barChartXValues.add(i + "h");
- for (int i = 0; i < appsRunDuration.size(); i++) {
- if (appsRunDuration.get(i).size() == 0) {
- barChartYValues.add(new BarEntry(0, i));
- continue;
- }
- float[] entries = new float[appsRunDuration.get(i).size()];
- for (int j = 0; j < appsRunDuration.get(i).size(); j++) {
- entries[j] = appsRunDuration.get(i).get(j).getDuration();
- }
- barChartYValues.add(new BarEntry(entries, i));
- }
- /* Now we have data. We can set marker */
- barChart.setMarkerView(new BarChartMarkerApp(context, R.layout.bar_chart_marker, appsRunDuration));
- barDataSet = new BarDataSet(barChartYValues, "");
- barDataSet.setColors(setCorrectColors(appsRunDuration));
- barDataSet.setDrawValues(false);
- }
- /**
- * Focus bar chart on bar witch has the mot actual values.
- */
- public void barChartSetViewCenter() {
- int index = 0;
- switch (index){
- default:
- index = DateTime.now().getHourOfDay();
- }
- barChart.centerViewToAnimated(index, 0, YAxis.AxisDependency.LEFT, ANIMATION_LENGTH);
- }
- /**
- * Initialize hash map, who maps package name to color.
- */
- public void initAppColorPalette() {
- appColorPalette = new ArrayList<>();
- int appColor,colorIndex;
- /* Go through all */
- for (AppUsage appUsage : usageStats) {
- /* Load app color */
- appColor = SharedPrefsAccess.loadInt(context,COLOR_PALETTE_KEY + appUsage.getPackageName());
- /* Look to shared preferences */
- if (appColor != -1) {
- appColorPalette.add(appColor);
- } else {
- /* Get index of last used color from color palette */
- colorIndex = SharedPrefsAccess.loadInt(context,COLOR_PALETTE_INDEX);
- if (colorIndex == -1) { colorIndex = 0; }
- /* App package name not found in shared preferences -> create new preference */
- SharedPrefsAccess.save(context,COLOR_PALETTE_KEY + appUsage.getPackageName(),
- ColorPalette.MOBILE_ACTIVITIES[colorIndex]);
- /* Add color to list */
- appColorPalette.add(ColorPalette.MOBILE_ACTIVITIES[colorIndex]);
- /* Save new color index */
- SharedPrefsAccess.save(context,COLOR_PALETTE_INDEX,
- ((colorIndex + 1) % ColorPalette.MOBILE_ACTIVITIES.length));
- }
- }
- }
- /**
- * Set color to dataset in way they correspond pieChart graph.
- */
- public List<Integer> setCorrectColors(List<List<AppRunDuration>> appsRunDuration) {
- List<Integer> colors = new ArrayList<>();
- /* Create mapping app -> color */
- Map<String,Integer> appToColor = new HashMap<>();
- for (int i = 0;i < usageStats.size();i++) {
- appToColor.put(usageStats.get(i).getPackageName(), appColorPalette.get(i));
- }
- for (int i = 0; i < appsRunDuration.size(); i++) {
- /* Even blank bars need color */
- if (appsRunDuration.get(i).size() == 0) {
- colors.add(Color.TRANSPARENT);
- }
- for (int j = 0; j < appsRunDuration.get(i).size(); j++) {
- /* Key not find -> app is in "OTHERS" */
- if (!appToColor.containsKey(appsRunDuration.get(i).get(j).getPackageName())) {
- colors.add(appToColor.get("OTHERS"));
- continue;
- }
- colors.add(appToColor.get(appsRunDuration.get(i).get(j).getPackageName()));
- }
- }
- return colors;
- }
- /**
- * Setup time span panel, handle clicks.
- */
- public void timeSpanPanel() {
- tvTimeSpan.setText(TimeSpan.getString(timeSpan, context));
- /* Handle button clicks */
- ibTimeSpanMinus.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- timeSpanMinus();
- }
- });
- ibTimeSpanPlus.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- timeSpanPlus();
- }
- });
- }
- /**
- * Change time span "-".
- */
- public void timeSpanMinus () {
- /* Get new time span */
- timeSpan = TimeSpan.previous(timeSpan);
- /* Set text */
- tvTimeSpan.setText(TimeSpan.getString(timeSpan,context));
- updatePieChart();
- }
- /**
- * Change time span "+".
- */
- public void timeSpanPlus () {
- /* Get new time span */
- timeSpan = TimeSpan.next(timeSpan);
- /* Set text */
- tvTimeSpan.setText(TimeSpan.getString(timeSpan,context));
- updatePieChart();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement