com.asksven.betterbatterystats.adapters.StatsAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.asksven.betterbatterystats.adapters.StatsAdapter.java

Source

/*
 * Copyright (C) 2011-2014 asksven
 *
 * 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 com.asksven.betterbatterystats.adapters;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.asksven.android.common.privateapiproxies.NativeKernelWakelock;
import com.asksven.android.common.kernelutils.State;
import com.asksven.android.common.nameutils.UidNameResolver;
import com.asksven.android.common.privateapiproxies.Alarm;
import com.asksven.android.common.privateapiproxies.AlarmItem;
import com.asksven.android.common.privateapiproxies.Misc;
import com.asksven.android.common.privateapiproxies.NetworkUsage;
import com.asksven.android.common.privateapiproxies.Process;
import com.asksven.android.common.privateapiproxies.SensorUsage;
import com.asksven.android.common.privateapiproxies.SensorUsageItem;
import com.asksven.android.common.privateapiproxies.StatElement;
import com.asksven.betterbatterystats.widgets.GraphableBars;
import com.asksven.betterbatterystats.widgets.GraphablePie;
import com.asksven.betterbatterystats.LogSettings;
import com.asksven.betterbatterystats.PackageInfoActivity;
import com.asksven.betterbatterystats.R;

public class StatsAdapter extends BaseAdapter {
    private Context m_context;

    private List<StatElement> m_listData;
    private static final String TAG = "StatsAdapter";
    public static final String TRANSITION_NAME = "icon_transition";

    private double m_maxValue = 0;
    private long m_timeSince = 0;
    private Activity m_parent = null;

    public StatsAdapter(Context context, List<StatElement> listData, Activity parent) {
        this.m_context = context;
        this.m_listData = listData;
        this.m_parent = parent;

        SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.m_context);
        boolean bKbEnabled = sharedPrefs.getBoolean("enable_kb", true);

        if ((m_listData != null) && (!m_listData.isEmpty())) {
            if (m_listData.get(0) instanceof NetworkUsage) {
                for (int i = 0; i < m_listData.size(); i++) {
                    StatElement g = m_listData.get(i);

                    double[] values = g.getValues();
                    m_maxValue = Math.max(m_maxValue, values[values.length - 1]);
                    m_maxValue = Math.max(m_maxValue, g.getMaxValue());
                }
            } else if (m_listData.get(0) instanceof Alarm) {
                for (int i = 0; i < m_listData.size(); i++) {
                    StatElement g = m_listData.get(i);

                    double[] values = g.getValues();
                    m_maxValue += values[0];
                    Log.i(TAG, "Summing up " + values[0] + ", max is now " + m_maxValue);
                }
            } else if (m_listData.get(0) instanceof SensorUsage) {
                for (int i = 0; i < m_listData.size(); i++) {
                    StatElement g = m_listData.get(i);

                    double[] values = g.getValues();
                    m_maxValue += values[0];
                    Log.i(TAG, "Summing up " + values[0] + ", max is now " + m_maxValue);
                }
            }

            else if (m_listData.get(0) instanceof Process) {
                StatElement g = m_listData.get(0);

                m_maxValue = g.getTotal();
                Log.i(TAG, "Total is " + m_maxValue);
            }

            else {
                m_maxValue = m_timeSince;
            }

        }
    }

    public int getCount() {
        if (m_listData != null) {
            return m_listData.size();
        } else {
            return 0;
        }
    }

    public Object getItem(int position) {
        return m_listData.get(position);
    }

    public void setTotalTime(long sinceMs) {
        m_timeSince = sinceMs;
        if ((m_listData == null) || (m_listData.isEmpty()))
            return;

        if (!((m_listData.get(0) instanceof Process) || (m_listData.get(0) instanceof NetworkUsage)
                || (m_listData.get(0) instanceof Alarm))) {
            m_maxValue = m_timeSince;
        }
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup viewGroup) {
        StatElement entry = m_listData.get(position);

        SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.m_context);
        boolean bShowBars = sharedPrefs.getBoolean("show_gauge", false);

        if (LogSettings.DEBUG) {
            Log.i(TAG, "Values: " + entry.getVals());
        }

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) m_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            // depending on settings show new pie gauge or old bar gauge
            if (!bShowBars) {
                convertView = inflater.inflate(R.layout.stat_row, null);
            } else {
                convertView = inflater.inflate(R.layout.stat_row_gauge, null);
            }
        }

        final float scale = this.m_context.getResources().getDisplayMetrics().density;

        TextView tvName = (TextView) convertView.findViewById(R.id.TextViewName);

        /////////////////////////////////////////
        // we do some stuff here to handle settings about font size and thumbnail size
        String fontSize = sharedPrefs.getString("medium_font_size", "16");
        int mediumFontSize = Integer.parseInt(fontSize);

        //we need to change "since" fontsize
        tvName.setTextSize(TypedValue.COMPLEX_UNIT_SP, mediumFontSize);

        // We need to handle an exception here: Sensors do not have a name so we use the fqn instead
        if (entry instanceof SensorUsage) {
            tvName.setText(entry.getFqn(UidNameResolver.getInstance(m_context)));

        } else {
            tvName.setText(entry.getName());
        }

        boolean bShowKb = sharedPrefs.getBoolean("enable_kb", true);
        ImageView iconKb = (ImageView) convertView.findViewById(R.id.imageKB);

        iconKb.setVisibility(View.INVISIBLE);

        TextView tvFqn = (TextView) convertView.findViewById(R.id.TextViewFqn);
        tvFqn.setText(entry.getFqn(UidNameResolver.getInstance(m_context)));

        TextView tvData = (TextView) convertView.findViewById(R.id.TextViewData);

        // for alarms the values is wakeups per hour so we need to take the time as reference for the text
        if (entry instanceof Alarm) {
            tvData.setText(entry.getData((long) m_timeSince));
        } else {
            tvData.setText(entry.getData((long) m_maxValue));
        }

        //LinearLayout myLayout = (LinearLayout) convertView.findViewById(R.id.LinearLayoutBar);
        LinearLayout myFqnLayout = (LinearLayout) convertView.findViewById(R.id.LinearLayoutFqn);
        LinearLayout myRow = (LinearLayout) convertView.findViewById(R.id.LinearLayoutEntry);

        // long press for "copy to clipboard"
        convertView.setOnLongClickListener(new OnItemLongClickListener(position));

        if (!bShowBars) {
            GraphablePie gauge = (GraphablePie) convertView.findViewById(R.id.Gauge);

            /////////////////////////////////////////
            // we do some stuff here to handle settings about font size and thumbnail size
            String iconDim = sharedPrefs.getString("thumbnail_size", "56");
            int iconSize = Integer.parseInt(iconDim);
            int pixels = (int) (iconSize * scale + 0.5f);
            //we need to change "since" fontsize
            gauge.getLayoutParams().height = pixels;
            gauge.getLayoutParams().width = pixels;
            gauge.requestLayout();

            ////////////////////////////////////////////////////////////////////////////////////
            if (entry instanceof NetworkUsage) {
                gauge.setValue(entry.getValues()[0], ((NetworkUsage) entry).getTotal());

            } else {
                double max = m_maxValue;
                // avoid rounding errors leading to values > 100 %
                if (entry.getValues()[0] > max) {
                    max = entry.getValues()[0];
                    Log.i(TAG, "Upping gauge max to " + max);
                }
                gauge.setValue(entry.getValues()[0], max);
            }
        } else {
            GraphableBars buttonBar = (GraphableBars) convertView.findViewById(R.id.ButtonBar);
            int iHeight = 10;
            try {
                iHeight = Integer.valueOf(sharedPrefs.getString("graph_bar_height", "10"));
            } catch (Exception e) {
                iHeight = 10;
            }
            if (iHeight == 0) {
                iHeight = 10;
            }

            buttonBar.setMinimumHeight(iHeight);
            buttonBar.setName(entry.getName());
            buttonBar.setValues(entry.getValues(), m_maxValue);
        }
        ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
        LinearLayout iconLayout = (LinearLayout) convertView.findViewById(R.id.LayoutIcon);
        /////////////////////////////////////////
        // we do some stuff here to handle settings about font size and thumbnail size
        String iconDim = sharedPrefs.getString("thumbnail_size", "56");
        int iconSize = Integer.parseInt(iconDim);
        int pixels = (int) (iconSize * scale + 0.5f);
        //we need to change "since" fontsize
        iconView.getLayoutParams().width = pixels;
        iconView.getLayoutParams().height = pixels;
        iconView.requestLayout();
        //n 20;setLay.setTextSize(TypedValue.COMPLEX_UNIT_DIP, iconSize);

        ////////////////////////////////////////////////////////////////////////////////////

        // add on click listener for the icon only if KB is enabled
        //        if (bShowKb)
        //        {
        //           // set a click listener for the list
        //           iconKb.setOnClickListener(new OnIconClickListener(position));
        //        }

        // show / hide fqn text
        if ((entry instanceof Process) || (entry instanceof State) || (entry instanceof Misc)
                || (entry instanceof NativeKernelWakelock) || (entry instanceof Alarm)
                || (entry instanceof SensorUsage)) {
            myFqnLayout.setVisibility(View.GONE);
        } else {
            myFqnLayout.setVisibility(View.VISIBLE);
        }

        // show / hide package icons (we show / hide the whole layout as it contains a margin that must be hidded as well
        if ((entry instanceof NativeKernelWakelock) || (entry instanceof State) || (entry instanceof Misc)) {

            iconView.setVisibility(View.GONE);

        } else {
            iconView.setVisibility(View.VISIBLE);
            iconView.setImageDrawable(entry.getIcon(UidNameResolver.getInstance(m_context)));
            // set a click listener for the list
            iconView.setOnClickListener(new OnPackageClickListener(position));

        }

        // add on click listener for the list entry if details are availble
        if ((entry instanceof Alarm) || (entry instanceof NativeKernelWakelock) || (entry instanceof SensorUsage)) {
            convertView.setOnClickListener(new OnItemClickListener(position));
        }

        //        // show / hide set dividers
        //        ListView myList = (ListView) convertView.getListView(); //findViewById(R.id.id.list);
        //        myList.setDivider(new ColorDrawable(0x99F10529));
        //        myList.setDividerHeight(1);
        return convertView;
    }

    //    /**
    //     * Handler for on click of the KB icon
    //     * @author sven
    //     *
    //     */
    //    private class OnIconClickListener implements OnClickListener
    //    {           
    //        private int m_iPosition;
    //        OnIconClickListener(int position)
    //        {
    //                m_iPosition = position;
    //        }
    //        
    //        @Override
    //        public void onClick(View arg0)
    //        {
    //           StatElement entry = (StatElement) getItem(m_iPosition);
    //            KbData kb = KbReader.getInstance().read(m_context);
    //           // the timing may lead to m_kb not being initialized yet, it must be checked
    //           if (kb == null)
    //           {
    //              return;
    //           }
    //           KbEntry kbentry = kb.findByStatElement(entry.getName(), entry.getFqn(UidNameResolver.getInstance(StatsAdapter.this.m_context)));
    //              if (kbentry != null)
    //              {
    //                 SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(StatsAdapter.this.m_context);
    //                 
    //                 String url = kbentry.getUrl();
    //                 
    //                if (sharedPrefs.getBoolean("kb_ext_browser", true))
    //                {
    //               
    //               Intent intent = new Intent("android.intent.action.VIEW",
    //                     Uri.parse(url)); 
    //               StatsAdapter.this.m_context.startActivity(intent);
    //                }
    //                else
    //                {
    //                    Intent intentKB = new Intent(StatsAdapter.this.m_context,
    //                          HelpActivity.class);
    //                    intentKB.putExtra("url", url);
    //                   StatsAdapter.this.m_context.startActivity(intentKB);
    //                }           
    //              }
    //        }
    //    }

    /**
     * Handler for on click of the icon
     * @author sven
     *
     */
    private class OnPackageClickListener implements OnClickListener {
        private int m_iPosition;

        OnPackageClickListener(int position) {
            m_iPosition = position;
        }

        @Override
        public void onClick(View arg0) {
            StatElement entry = (StatElement) getItem(m_iPosition);

            Context ctx = arg0.getContext();
            if (entry.getIcon(UidNameResolver.getInstance(m_context)) == null) {
                return;
            }

            //           ctx.startActivity(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS));
            String packageName = entry.getPackageName();
            showInstalledPackageDetails(ctx, packageName, arg0);

        }
    }

    /**
     * Handler for the on click of the list item
     * @author sven
     *
     */
    private class OnItemClickListener implements OnClickListener {
        private int m_iPosition;

        OnItemClickListener(int position) {
            m_iPosition = position;
        }

        @SuppressLint("NewApi")
        @Override
        public void onClick(View arg0) {

            StatElement entry = (StatElement) getItem(m_iPosition);

            if (entry instanceof SensorUsage) {
                SensorUsage sensorEntry = (SensorUsage) getItem(m_iPosition);

                Dialog dialog = new Dialog(m_context);
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setContentView(R.layout.details_dialog);

                TextView dialogTitle = (TextView) dialog.findViewById(R.id.dialog_title);
                dialogTitle.setText(entry.getFqn(UidNameResolver.getInstance(m_context)));
                TextView title = (TextView) dialog.findViewById(R.id.title);
                TextView text = (TextView) dialog.findViewById(R.id.text);
                title.setText(entry.getData((long) m_timeSince));

                String strText = "";
                ArrayList<SensorUsageItem> myItems = sensorEntry.getItems();
                if (myItems != null) {
                    for (int i = 0; i < myItems.size(); i++) {
                        if (myItems.get(i).getTime() > 0) {
                            strText = strText + myItems.get(i).getData() + "\n\n";
                        }
                    }
                }
                text.setText(strText);
                dialog.show();
            }

            if (entry instanceof Alarm) {
                Alarm alarmEntry = (Alarm) getItem(m_iPosition);

                Dialog dialog = new Dialog(m_context);
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setContentView(R.layout.details_dialog);

                TextView dialogTitle = (TextView) dialog.findViewById(R.id.dialog_title);
                dialogTitle.setText(entry.getName());
                TextView title = (TextView) dialog.findViewById(R.id.title);
                TextView text = (TextView) dialog.findViewById(R.id.text);
                title.setText(entry.getData((long) m_timeSince));

                String strText = "";
                ArrayList<AlarmItem> myItems = alarmEntry.getItems();
                if (myItems != null) {
                    for (int i = 0; i < myItems.size(); i++) {
                        if (myItems.get(i).getCount() > 0) {
                            strText = strText + myItems.get(i).getData() + "\n\n";
                        }
                    }
                }
                text.setText(strText);
                dialog.show();
            }

            if (entry instanceof NativeKernelWakelock) {
                NativeKernelWakelock kernelWakelockEntry = (NativeKernelWakelock) getItem(m_iPosition);

                Dialog dialog = new Dialog(m_context);
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setContentView(R.layout.details_dialog);
                dialog.setTitle(kernelWakelockEntry.getName());

                TextView dialogTitle = (TextView) dialog.findViewById(R.id.dialog_title);
                dialogTitle.setText(kernelWakelockEntry.getName());
                TextView title = (TextView) dialog.findViewById(R.id.title);
                //               TextView subtitle = (TextView) dialog.findViewById(R.id.subtitle);
                TextView text = (TextView) dialog.findViewById(R.id.text);
                title.setText(kernelWakelockEntry.getData((long) m_maxValue));

                String strText = "";
                strText += "Count: " + kernelWakelockEntry.getCount() + "\n";
                strText += "Expire Count: " + kernelWakelockEntry.getExpireCount() + "\n";
                strText += "Wake Count: " + kernelWakelockEntry.getWakeCount() + "\n";
                strText += "Total Time: " + kernelWakelockEntry.getTtlTime() + "\n";
                strText += "Sleep Time: " + kernelWakelockEntry.getSleepTime() + "\n";
                strText += "Max Time: " + kernelWakelockEntry.getMaxTime() + "\n";

                text.setText(strText);
                dialog.show();

            }
        }
    }

    /**
     * Handler for the on click of the list item
     * @author sven
     *
     */
    private class OnItemLongClickListener implements OnLongClickListener {
        private int m_iPosition;

        OnItemLongClickListener(int position) {
            m_iPosition = position;
        }

        @SuppressLint("NewApi")
        @Override
        public boolean onLongClick(View arg0) {
            StatElement entry = (StatElement) getItem(m_iPosition);
            if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
                android.text.ClipboardManager clipboard = (android.text.ClipboardManager) m_context
                        .getSystemService(Context.CLIPBOARD_SERVICE);
                clipboard.setText(entry.getName());
            } else {
                android.content.ClipboardManager clipboard = (android.content.ClipboardManager) m_context
                        .getSystemService(Context.CLIPBOARD_SERVICE);
                android.content.ClipData clip = android.content.ClipData.newPlainText("Copied Text",
                        entry.getName());
                clipboard.setPrimaryClip(clip);
            }
            try {
                Toast.makeText(m_context,
                        m_context.getString(R.string.message_copied_to_clipboard, entry.getName()),
                        Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                // can normally not fail, if it still does it's only the toast
            }
            return true;
        }
    }

    public void showInstalledPackageDetails(Context context, String packageName, View view) {
        Intent intentPerms = new Intent(context, PackageInfoActivity.class);
        intentPerms.putExtra("package", packageName);
        //context.startActivity(intentPerms);
        View source_icon = view.findViewById(R.id.icon);

        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(m_parent, source_icon,
                TRANSITION_NAME);
        ActivityCompat.startActivity(m_parent, intentPerms, options.toBundle());

    }

}