@Override protected StatsAdapter doInBackground(Boolean... refresh) { // do we need to refresh current if (refresh[0]) { // make sure to create a valid "current" stat StatsProvider.getInstance(StatsActivity.this).setCurrentReference(m_iSorting); } // super.doInBackground(params); m_listViewAdapter = null; try { Log.i( TAG, "LoadStatData: refreshing display for stats " + m_refFromName + " to " + m_refToName); m_listViewAdapter = new StatsAdapter( StatsActivity.this, StatsProvider.getInstance(StatsActivity.this) .getStatList(m_iStat, m_refFromName, m_iSorting, m_refToName)); } catch (BatteryInfoUnavailableException e) { // Log.e(TAG, e.getMessage(), e.fillInStackTrace()); Log.e(TAG, "Exception: " + Log.getStackTraceString(e)); m_exception = e; } catch (Exception e) { // Log.e(TAG, e.getMessage(), e.fillInStackTrace()); Log.e(TAG, "Exception: " + Log.getStackTraceString(e)); m_exception = e; } // StatsActivity.this.setListAdapter(m_listViewAdapter); // getStatList(); return m_listViewAdapter; }
/* Request updates at startup */ @Override protected void onResume() { Log.i(TAG, "OnResume called"); super.onResume(); // register the broadcast receiver IntentFilter intentFilter = new IntentFilter(ReferenceStore.REF_UPDATED); m_referenceSavedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // extract our message from intent String refName = intent.getStringExtra(Reference.EXTRA_REF_NAME); // log our message value Log.i(TAG, "Received broadcast, reference was updated:" + refName); // reload the spinners to make sure all refs are in the right sequence when current gets // refreshed // if (refName.equals(Reference.CURRENT_REF_FILENAME)) // { refreshSpinners(); // } } }; // registering our receiver this.registerReceiver(m_referenceSavedReceiver, intentFilter); // the service is always started as it handles the widget updates too SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); boolean serviceShouldBeRunning = sharedPrefs.getBoolean("ref_for_screen_off", false); if (serviceShouldBeRunning) { if (!EventWatcherService.isServiceRunning(this)) { Intent i = new Intent(this, EventWatcherService.class); this.startService(i); } } // make sure to create a valid "current" stat if none exists // or if prefs re set to auto refresh boolean bAutoRefresh = sharedPrefs.getBoolean("auto_refresh", true); if ((bAutoRefresh) || (!ReferenceStore.hasReferenceByName(Reference.CURRENT_REF_FILENAME, this))) { Intent serviceIntent = new Intent(this, WriteCurrentReferenceService.class); this.startService(serviceIntent); doRefresh(true); } else { refreshSpinners(); doRefresh(false); } // check if active monitoring is on: if yes make sure the alarm is scheduled if (sharedPrefs.getBoolean("active_mon_enabled", false)) { if (!StatsProvider.isActiveMonAlarmScheduled(this)) { StatsProvider.scheduleActiveMonAlarm(this); } } }
// @Override protected void onPostExecute(StatsAdapter o) { // super.onPostExecute(o); // update hourglass try { if (m_progressDialog != null) { m_progressDialog.dismiss(); // hide(); m_progressDialog = null; } } catch (Exception e) { // nop } finally { m_progressDialog = null; } if (m_exception != null) { if (m_exception instanceof BatteryInfoUnavailableException) { Toast.makeText( StatsActivity.this, "BatteryInfo Service could not be contacted.", Toast.LENGTH_LONG) .show(); } else { Toast.makeText( StatsActivity.this, "An unknown error occured while retrieving stats.", Toast.LENGTH_LONG) .show(); } } TextView tvSince = (TextView) findViewById(R.id.TextViewSince); Reference myReferenceFrom = ReferenceStore.getReferenceByName(m_refFromName, StatsActivity.this); Reference myReferenceTo = ReferenceStore.getReferenceByName(m_refToName, StatsActivity.this); long sinceMs = StatsProvider.getInstance(StatsActivity.this).getSince(myReferenceFrom, myReferenceTo); if (sinceMs != -1) { String sinceText = DateUtils.formatDuration(sinceMs); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(StatsActivity.this); boolean bShowBatteryLevels = sharedPrefs.getBoolean("show_batt", true); if (bShowBatteryLevels) { sinceText += " " + StatsProvider.getInstance(StatsActivity.this) .getBatteryLevelFromTo(myReferenceFrom, myReferenceTo); } tvSince.setText(sinceText); Log.i(TAG, "Since " + sinceText); } else { tvSince.setText("n/a"); Log.i(TAG, "Since: n/a "); } StatsActivity.this.setListAdapter(o); }
/** * In order to refresh the ListView we need to re-create the Adapter (should be the case but * notifyDataSetChanged doesn't work so we recreate and set a new one) */ private void setListViewAdapter() throws Exception { // make sure we only instanciate when the reference does not exist if (m_listViewAdapter == null) { m_listViewAdapter = new StatsAdapter( this, StatsProvider.getInstance(this) .getStatList(m_iStat, m_refFromName, m_iSorting, m_refToName)); setListAdapter(m_listViewAdapter); } }
@Override public void onHandleIntent(Intent intent) { Log.i(TAG, "Called at " + DateUtils.now()); try { Wakelock.aquireWakelock(this); // Store the "custom StatsProvider.getInstance(this).setCurrentReference(0); // Build the intent to update the widget Intent intentRefreshWidgets = new Intent(LargeWidgetProvider.WIDGET_UPDATE); this.sendBroadcast(intentRefreshWidgets); Intent i = new Intent(ReferenceStore.REF_UPDATED) .putExtra(Reference.EXTRA_REF_NAME, Reference.CURRENT_REF_FILENAME); this.sendBroadcast(i); } catch (Exception e) { Log.e(TAG, "An error occured: " + e.getMessage()); } finally { Wakelock.releaseWakelock(); } stopSelf(); }
/** * Take the change of selection from the spinners into account and refresh the ListView with the * right data */ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) { // this method is fired even if nothing has changed so we nee to find that out SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); boolean bChanged = false; // id is in the order of the spinners, 0 is stat, 1 is stat_type if (parent == (Spinner) findViewById(R.id.spinnerStatType)) { // detect if something changed String newStat = (String) ((ReferencesAdapter) parent.getAdapter()).getItemName(position); if ((m_refFromName != null) && (!m_refFromName.equals(newStat))) { Log.i(TAG, "Spinner from changed from " + m_refFromName + " to " + newStat); m_refFromName = newStat; bChanged = true; // we need to update the second spinner m_spinnerToAdapter.filterToSpinner(newStat, this); m_spinnerToAdapter.notifyDataSetChanged(); // select the right element Spinner spinnerStatSampleEnd = (Spinner) findViewById(R.id.spinnerStatSampleEnd); if (spinnerStatSampleEnd.isShown()) { spinnerStatSampleEnd.setSelection(m_spinnerToAdapter.getPosition(m_refToName)); } else { spinnerStatSampleEnd.setSelection( m_spinnerToAdapter.getPosition(Reference.CURRENT_REF_FILENAME)); } } else { return; } } else if (parent == (Spinner) findViewById(R.id.spinnerStatSampleEnd)) { String newStat = (String) ((ReferencesAdapter) parent.getAdapter()).getItemName(position); if ((m_refFromName != null) && (!m_refToName.equals(newStat))) { Log.i(TAG, "Spinner to changed from " + m_refToName + " to " + newStat); m_refToName = newStat; bChanged = true; } else { return; } } else if (parent == (Spinner) findViewById(R.id.spinnerStat)) { int iNewStat = position; if (m_iStat != iNewStat) { m_iStat = iNewStat; bChanged = true; } else { return; } // inform the user when he tries to use functions requiring root and he doesn't have root // enabled boolean rootEnabled = sharedPrefs.getBoolean("root_features", false); if (!rootEnabled) { if ((m_iStat == 4) || (m_iStat == 3)) { Toast.makeText( this, "This function requires root access. Check \"Advanced\" preferences", Toast.LENGTH_LONG) .show(); } } } else { Log.e(TAG, "ProcessStatsActivity.onItemSelected error. ID could not be resolved"); Toast.makeText(this, "Error: could not resolve what changed", Toast.LENGTH_SHORT).show(); } Reference myReferenceFrom = ReferenceStore.getReferenceByName(m_refFromName, this); Reference myReferenceTo = ReferenceStore.getReferenceByName(m_refToName, this); TextView tvSince = (TextView) findViewById(R.id.TextViewSince); // long sinceMs = getSince(); long sinceMs = StatsProvider.getInstance(this).getSince(myReferenceFrom, myReferenceTo); if (sinceMs != -1) { String sinceText = DateUtils.formatDuration(sinceMs); boolean bShowBatteryLevels = sharedPrefs.getBoolean("show_batt", true); if (bShowBatteryLevels) { sinceText += " " + StatsProvider.getInstance(this) .getBatteryLevelFromTo(myReferenceFrom, myReferenceTo); } tvSince.setText(sinceText); Log.i(TAG, "Since " + sinceText); } else { tvSince.setText("n/a "); Log.i(TAG, "Since: n/a "); } // @todo fix this: this method is called twice // m_listViewAdapter.notifyDataSetChanged(); if (bChanged) { GoogleAnalytics.getInstance(this) .trackStats( this, GoogleAnalytics.ACTIVITY_STATS, m_iStat, m_refFromName, m_refToName, m_iSorting); // new LoadStatData().execute(this); // as the source changed fetch the data doRefresh(false); } }
/** @see android.app.Activity#onCreate(Bundle@SuppressWarnings("rawtypes") */ @Override protected void onCreate(Bundle savedInstanceState) { Log.i(TAG, "OnCreated called"); super.onCreate(savedInstanceState); setContentView(R.layout.stats); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); // set debugging if (sharedPrefs.getBoolean("debug_logging", false)) { LogSettings.DEBUG = true; CommonLogSettings.DEBUG = true; } else { LogSettings.DEBUG = false; CommonLogSettings.DEBUG = false; } // Check if the stats are accessible and warn if not BatteryStatsProxy stats = BatteryStatsProxy.getInstance(this); if (stats.initFailed()) { Toast.makeText( this, "The 'batteryinfo' service could not be accessed. If this error persists after a reboot please contact the dev and provide your ROM/Kernel versions.", Toast.LENGTH_SHORT) .show(); } /////////////////////////////////////////////// // check if we have a new release /////////////////////////////////////////////// // if yes do some migration (if required) and show release notes String strLastRelease = sharedPrefs.getString("last_release", "0"); String strCurrentRelease = ""; try { PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0); strCurrentRelease = Integer.toString(pinfo.versionCode); } catch (Exception e) { // nop strCurrentRelease is set to "" } if (strLastRelease.equals("0")) { // show the initial run screen FirstLaunch.app_launched(this); } else if (!strLastRelease.equals(strCurrentRelease)) { // save the current release to properties so that the dialog won't be shown till next version SharedPreferences.Editor updater = sharedPrefs.edit(); updater.putString("last_release", strCurrentRelease); updater.commit(); boolean migrated = false; ////////////////////////////////////////////////////////////////////////// // Fix for bad migration to 1.12 ////////////////////////////////////////////////////////////////////////// if (!sharedPrefs.getString("default_stat_type", "0").startsWith("ref_")) { Log.i( TAG, "Migrating default_stat_type, value was " + sharedPrefs.getString("default_stat_type", "0")); SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("default_stat_type", Reference.UNPLUGGED_REF_FILENAME); editor.commit(); migrated = true; } if (!sharedPrefs.getString("small_widget_default_stat_type", "0").startsWith("ref_")) { Log.i( TAG, "Migrating small_widget_default_stat_type, value was " + sharedPrefs.getString("small_widget_default_stat_type", "0")); SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("small_widget_default_stat_type", Reference.UNPLUGGED_REF_FILENAME); editor.commit(); migrated = true; } if (!sharedPrefs.getString("widget_fallback_stat_type", "0").startsWith("ref_")) { Log.i( TAG, "Migrating widget_fallback_stat_type, value was " + sharedPrefs.getString("widget_fallback_stat_type", "0")); SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("widget_fallback_stat_type", Reference.BOOT_REF_FILENAME); editor.commit(); migrated = true; } if (!sharedPrefs.getString("large_widget_default_stat_type", "0").startsWith("ref_")) { Log.i( TAG, "Migrating large_widget_default_stat_type, value was " + sharedPrefs.getString("large_widget_default_stat_type", "0")); SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("large_widget_default_stat_type", Reference.UNPLUGGED_REF_FILENAME); editor.commit(); migrated = true; } if (migrated) { Log.i(TAG, "Some preferences were migrated"); Toast.makeText(this, "Upgrading data.", Toast.LENGTH_SHORT).show(); } if (strCurrentRelease.equals("38")) { // we have changed the serialized format: delete reference and re-create umplugged and boot Toast.makeText(this, "Deleting and re-creating references", Toast.LENGTH_SHORT).show(); ReferenceStore.deleteAllRefs(this); Intent i = new Intent(this, WriteBootReferenceService.class); this.startService(i); i = new Intent(this, WriteUnpluggedReferenceService.class); this.startService(i); } // show the readme Intent intentReleaseNotes = new Intent(this, ReadmeActivity.class); intentReleaseNotes.putExtra("filename", "readme.html"); this.startActivity(intentReleaseNotes); } else { // can't do this at the same time as the popup dialog would be masked by the readme /////////////////////////////////////////////// // check if we have shown the opt-out from analytics /////////////////////////////////////////////// boolean bWarningShown = sharedPrefs.getBoolean("analytics_opt_out", false); boolean bAnalyticsEnabled = sharedPrefs.getBoolean("use_analytics", true); if (bAnalyticsEnabled && !bWarningShown) { // prepare the alert box AlertDialog.Builder alertbox = new AlertDialog.Builder(this); // set the message to display alertbox.setMessage( "BetterBatteryStats makes use of Google Analytics to collect usage statitics. If you disagree or do not want to participate you can opt-out by disabling \"Google Analytics\" in the \"Advanced Preferences\""); // add a neutral button to the alert box and assign a click listener alertbox.setNeutralButton( "Ok", new DialogInterface.OnClickListener() { // click listener on the alert box public void onClick(DialogInterface arg0, int arg1) { // opt out info was displayed SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(StatsActivity.this); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("analytics_opt_out", true); editor.commit(); } }); // show it alertbox.show(); } else { // show "rate" dialog // for testing: AppRater.showRateDialog(this, null); AppRater.app_launched(this); } } /////////////////////////////////////////////// // retrieve default selections for spinners // if none were passed /////////////////////////////////////////////// m_iStat = Integer.valueOf(sharedPrefs.getString("default_stat", "0")); m_refFromName = sharedPrefs.getString("default_stat_type", Reference.UNPLUGGED_REF_FILENAME); if (!ReferenceStore.hasReferenceByName(m_refFromName, this)) { if (sharedPrefs.getBoolean("fallback_to_since_boot", false)) { m_refFromName = Reference.BOOT_REF_FILENAME; Toast.makeText(this, "Fallback to 'Since Boot'", Toast.LENGTH_SHORT).show(); } } try { // recover any saved state if ((savedInstanceState != null) && (!savedInstanceState.isEmpty())) { m_iStat = (Integer) savedInstanceState.getSerializable("stat"); m_refFromName = (String) savedInstanceState.getSerializable("stattypeFrom"); m_refToName = (String) savedInstanceState.getSerializable("stattypeTo"); } } catch (Exception e) { m_iStat = Integer.valueOf(sharedPrefs.getString("default_stat", "0")); m_refFromName = sharedPrefs.getString("default_stat_type", Reference.UNPLUGGED_REF_FILENAME); Log.e(TAG, "Exception: " + e.getMessage()); DataStorage.LogToFile(LOGFILE, "Exception in onCreate restoring Bundle"); DataStorage.LogToFile(LOGFILE, e.getMessage()); DataStorage.LogToFile(LOGFILE, e.getStackTrace()); Toast.makeText( this, "An error occured while recovering the previous state", Toast.LENGTH_SHORT) .show(); } // Handle the case the Activity was called from an intent with paramaters Bundle extras = getIntent().getExtras(); if (extras != null) { // Override if some values were passed to the intent m_iStat = extras.getInt(StatsActivity.STAT); m_refFromName = extras.getString(StatsActivity.STAT_TYPE_FROM); m_refToName = extras.getString(StatsActivity.STAT_TYPE_TO); boolean bCalledFromNotification = extras.getBoolean(StatsActivity.FROM_NOTIFICATION, false); // Clear the notifications that was clicked to call the activity if (bCalledFromNotification) { NotificationManager nM = (NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE); nM.cancel(EventWatcherService.NOTFICATION_ID); } } // Display the reference of the stat TextView tvSince = (TextView) findViewById(R.id.TextViewSince); if (tvSince != null) { Reference myReferenceFrom = ReferenceStore.getReferenceByName(m_refFromName, this); Reference myReferenceTo = ReferenceStore.getReferenceByName(m_refToName, this); long sinceMs = StatsProvider.getInstance(this).getSince(myReferenceFrom, myReferenceTo); if (sinceMs != -1) { String sinceText = DateUtils.formatDuration(sinceMs); boolean bShowBatteryLevels = sharedPrefs.getBoolean("show_batt", true); if (bShowBatteryLevels) { sinceText += " " + StatsProvider.getInstance(this) .getBatteryLevelFromTo(myReferenceFrom, myReferenceTo); } tvSince.setText(sinceText); Log.i(TAG, "Since " + sinceText); } else { tvSince.setText("n/a"); Log.i(TAG, "Since: n/a "); } } // Spinner for selecting the stat Spinner spinnerStat = (Spinner) findViewById(R.id.spinnerStat); ArrayAdapter spinnerStatAdapter = ArrayAdapter.createFromResource(this, R.array.stats, android.R.layout.simple_spinner_item); spinnerStatAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerStat.setAdapter(spinnerStatAdapter); // setSelection MUST be called after setAdapter spinnerStat.setSelection(m_iStat); spinnerStat.setOnItemSelectedListener(this); /////////////////////////////////////////////// // Spinner for Selecting the Stat type /////////////////////////////////////////////// Spinner spinnerStatType = (Spinner) findViewById(R.id.spinnerStatType); m_spinnerFromAdapter = new ReferencesAdapter(this, android.R.layout.simple_spinner_item); m_spinnerFromAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerStatType.setAdapter(m_spinnerFromAdapter); try { this.setListViewAdapter(); } catch (BatteryInfoUnavailableException e) { // Log.e(TAG, e.getMessage(), e.fillInStackTrace()); Log.e(TAG, "Exception: " + Log.getStackTraceString(e)); Toast.makeText(this, "BatteryInfo Service could not be contacted.", Toast.LENGTH_LONG).show(); } catch (Exception e) { // Log.e(TAG, e.getMessage(), e.fillInStackTrace()); Log.e(TAG, "Exception: " + Log.getStackTraceString(e)); Toast.makeText( this, "An unhandled error occured. Please check your logcat", Toast.LENGTH_LONG) .show(); } // setSelection MUST be called after setAdapter spinnerStatType.setSelection(m_spinnerFromAdapter.getPosition(m_refFromName)); spinnerStatType.setOnItemSelectedListener(this); /////////////////////////////////////////////// // Spinner for Selecting the end sample /////////////////////////////////////////////// Spinner spinnerStatSampleEnd = (Spinner) findViewById(R.id.spinnerStatSampleEnd); m_spinnerToAdapter = new ReferencesAdapter(this, android.R.layout.simple_spinner_item); m_spinnerToAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); boolean bShowSpinner = sharedPrefs.getBoolean("show_to_ref", true); if (bShowSpinner) { spinnerStatSampleEnd.setVisibility(View.VISIBLE); spinnerStatSampleEnd.setAdapter(m_spinnerToAdapter); // setSelection must be called after setAdapter if ((m_refToName != null) && !m_refToName.equals("")) { int pos = m_spinnerToAdapter.getPosition(m_refToName); spinnerStatSampleEnd.setSelection(pos); } else { spinnerStatSampleEnd.setSelection( m_spinnerToAdapter.getPosition(Reference.CURRENT_REF_FILENAME)); } } else { spinnerStatSampleEnd.setVisibility(View.GONE); spinnerStatSampleEnd.setAdapter(m_spinnerToAdapter); // setSelection must be called after setAdapter spinnerStatSampleEnd.setSelection( m_spinnerToAdapter.getPosition(Reference.CURRENT_REF_FILENAME)); } spinnerStatSampleEnd.setOnItemSelectedListener(this); /////////////////////////////////////////////// // sorting /////////////////////////////////////////////// String strOrderBy = sharedPrefs.getString("default_orderby", "0"); try { m_iSorting = Integer.valueOf(strOrderBy); } catch (Exception e) { // handle error here m_iSorting = 0; } GoogleAnalytics.getInstance(this) .trackStats( this, GoogleAnalytics.ACTIVITY_STATS, m_iStat, m_refFromName, m_refToName, m_iSorting); // Set up a listener whenever a key changes PreferenceManager.getDefaultSharedPreferences(this) .registerOnSharedPreferenceChangeListener(this); // log reference store ReferenceStore.logReferences(this); }