Java tutorial
/* * Copyright (C) 2013 - Gareth Llewellyn * * This file is part of Rhybudd - http://blog.NetworksAreMadeOfString.co.uk/Rhybudd/ * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/> */ package net.networksaremadeofstring.rhybudd; import android.app.ActionBar; import android.app.AlertDialog; import android.app.NotificationManager; import android.app.ProgressDialog; import android.app.backup.BackupManager; import android.content.*; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.preference.PreferenceManager; import android.provider.Settings; import android.support.v4.app.*; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.text.format.Time; import android.util.Log; import android.view.*; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.widget.*; import com.bugsense.trace.BugSenseHandler; import com.google.android.gcm.GCMRegistrar; import java.util.ArrayList; import java.util.List; public class RhybuddHome extends FragmentActivity { private static final int INFRASTRUCTURE = 0; private static final int MANAGEDATABASE = 1; private static final int GROUPS = 2; private static final int SETTINGS = 3; private static final int CONFIGURERHYBUDDPUSH = 4; private static final int HELP = 5; private static final int FEEDBACK = 6; SharedPreferences settings = null; ZenossAPI API = null; List<ZenossEvent> listOfZenossEvents = new ArrayList<ZenossEvent>(); List<Integer> selectedEvents = new ArrayList<Integer>(); Thread dataPreload, AckEvent; volatile Handler handler, AckEventHandler; ProgressDialog dialog; AlertDialog alertDialog; ListView list; ZenossEventsAdaptor adapter; ActionBar actionbar; int requestCode; ActionMode mActionMode; FragmentManager fragmentManager; FragmentTransaction fragmentTransaction; boolean FragmentVisible = false; int selectedFragmentEvent = 0; String regId = ""; ZenossPoller mService; boolean mBound = false; int retryCount = 0; boolean firstRun = false; boolean resumeOnResultPollAPI = true; private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; private String[] mDrawerTitles; @Override public void onAttachedToWindow() { super.onAttachedToWindow(); try { Window window = getWindow(); window.setFormat(PixelFormat.RGBA_8888); } catch (Exception e) { //TODO Do something although I doubt this will ever happen } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); setContentView(R.layout.rhybudd_home); finishStart(false); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public void onNewIntent(Intent newIntent) { ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)) .cancel(Notifications.NOTIFICATION_POLLED_ALERTS); if (newIntent.getBooleanExtra("forceRefresh", false)) { DBGetThread(); } } @Override protected void onResume() { super.onResume(); //Can't hurt to try and start the service just in case startService(new Intent(this, ZenossPoller.class)); //User is about to see the list of events - no need for them to hang around ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)) .cancel(Notifications.NOTIFICATION_POLLED_ALERTS); ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)) .cancel(Notifications.NOTIFICATION_GCM_GENERIC); //Lets try and bind to our service (if it's alive) doBindService(); //Might as well update GCM whilst we're here if (settings.contains(ZenossAPI.PREFERENCE_PUSHKEY) && !settings.getString(ZenossAPI.PREFERENCE_PUSHKEY, "").equals("")) { doGCMRegistration(settings.getString(ZenossAPI.PREFERENCE_PUSHKEY, "")); } //OnCreate checks the settings for various bits. If they aren't there it sets first run to true //Checking a single bool is a hell of a lot more lightweight than 3 Preferences each onResume ! if (firstRun) { //We need to set this now as no doubt on resume gets called before onActivityResult firstRun = false; Intent SettingsIntent = new Intent(RhybuddHome.this, FirstRunSettings.class); SettingsIntent.putExtra("firstRun", true); //Test RhybuddHome.this.startActivityForResult(SettingsIntent, requestCode); } else { boolean lastCheckRequired = false; if (null != settings && settings.contains("lastCheck")) { Time now = new Time(); now.setToNow(); Long timesinceLastRefresh = (now.toMillis(true) - settings.getLong("lastCheck", 0)); Log.e("timesinceLastRefresh", Long.toString(timesinceLastRefresh)); if (timesinceLastRefresh > 900000) { lastCheckRequired = true; } } //If we've resumed from one of our own activities we probably don't want to do a full refresh //finishStart will force a full refresh if backgroundPolling isn't enabled //if(resumeOnResultPollAPI || lastCheckRequired) if (resumeOnResultPollAPI) { finishStart(false); //Refresh(); } else { //Nice and fast for returning from within our own app DBGetThread(); resumeOnResultPollAPI = true; } } } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); BugSenseHandler.initAndStartSession(RhybuddHome.this, "44a76a8c"); settings = PreferenceManager.getDefaultSharedPreferences(this); setContentView(R.layout.rhybudd_home); actionbar = getActionBar(); actionbar.setTitle("Rhybudd Events List"); actionbar.setSubtitle(settings.getString("URL", "")); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); if ((settings.getString("URL", "").equals("") || settings.getString("userName", "").equals("") || settings.getString("passWord", "").equals(""))) { firstRun = true; } mDrawerTitles = getResources().getStringArray(R.array.drawer_array); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer); mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mDrawerTitles)); mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */ R.string.drawer_open, /* "open drawer" description for accessibility */ R.string.drawer_close /* "close drawer" description for accessibility */ ) { public void onDrawerClosed(View view) { //getActionBar().setTitle(mTitle); //invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } public void onDrawerOpened(View drawerView) { // getActionBar().setTitle(mDrawerTitle); // invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } }; mDrawerLayout.setDrawerListener(mDrawerToggle); } private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { ProcessDrawerClick(position); } } private void ProcessDrawerClick(int position) { switch (position) { case SETTINGS: { Intent SettingsIntent = new Intent(RhybuddHome.this, SettingsFragment.class); this.startActivityForResult(SettingsIntent, 99); } break; case CONFIGURERHYBUDDPUSH: { Intent PushSettingsIntent = new Intent(RhybuddHome.this, PushConfigActivity.class); this.startActivityForResult(PushSettingsIntent, ZenossAPI.ACTIVITYRESULT_PUSHCONFIG); } break; case HELP: { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse("http://wiki.zenoss.org/index.php?title=Rhybudd#Getting_Started")); startActivityForResult(i, 20); } break; case INFRASTRUCTURE: { Intent DeviceList = new Intent(RhybuddHome.this, ViewZenossDeviceListActivity.class); RhybuddHome.this.startActivityForResult(DeviceList, 20); } break; case GROUPS: { Intent GroupsIntent = new Intent(RhybuddHome.this, ViewZenossGroupsActivity.class); RhybuddHome.this.startActivityForResult(GroupsIntent, 20); } break; case MANAGEDATABASE: { Intent MangeDBIntent = new Intent(RhybuddHome.this, ManageDatabase.class); RhybuddHome.this.startActivityForResult(MangeDBIntent, 20); } break; case FEEDBACK: { try { Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", "Gareth@DataSift.com", null)); emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Feedback suggestion for Rhybudd"); startActivity(Intent.createChooser(emailIntent, "Send feedback as email")); } catch (Exception e) { Toast.makeText(RhybuddHome.this, "There was a problem launching your email client.\n\nPlease email Gareth@DataSift.com with your feedback.", Toast.LENGTH_LONG).show(); } } break; } // update selected item and title, then close the drawer //mDrawerList.setItemChecked(position, true); mDrawerLayout.closeDrawer(mDrawerList); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } public void DBGetThread() { Log.e("DBGetThread", "Doing a DB lookup"); listOfZenossEvents.clear(); dataPreload = new Thread() { public void run() { List<ZenossEvent> tempZenossEvents = null; try { RhybuddDataSource datasource = new RhybuddDataSource(RhybuddHome.this); datasource.open(); tempZenossEvents = datasource.GetRhybuddEvents(); datasource.close(); } catch (Exception e) { e.printStackTrace(); if (tempZenossEvents != null) tempZenossEvents.clear(); } if (tempZenossEvents != null && tempZenossEvents.size() > 0) { try { listOfZenossEvents = tempZenossEvents; //Log.i("EventList","Found DB Data!"); handler.sendEmptyMessage(1); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("RhybuddHome", "DBGetThread", e); } } else { Log.i("EventList", "No DB data found, querying API directly"); try { handler.sendEmptyMessage(2); if (tempZenossEvents != null) tempZenossEvents.clear(); //Can we get away with just calling refresh now? //TODO This needs to be sent as a runnable or something Refresh(); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("RhybuddHome", "DBGetThread", e); } } } }; dataPreload.start(); } public void Refresh() { Log.i("RhybuddHOMe", "Performing a Direct API Refresh"); try { if (dialog == null || !dialog.isShowing()) { dialog = new ProgressDialog(this); } dialog.setTitle("Querying Zenoss Directly"); dialog.setMessage("Refreshing Events..."); //dialog.setCancelable(false); if (!dialog.isShowing()) dialog.show(); } catch (Exception e) { e.printStackTrace(); //TODO Handle this and tell the user BugSenseHandler.sendExceptionMessage("RhybuddHome", "Refresh", e); } ((Thread) new Thread() { public void run() { List<ZenossEvent> tempZenossEvents = null; //This is a bit dirty but hell it saves an extra API call if (null == mService && !mBound) { Log.e("Refresh", "Service was dead or something so sleeping"); try { sleep(500); } catch (Exception e) { } } if (null != mService && mBound) { Log.e("Refresh", "yay not dead"); try { if (null == mService.API) { mService.PrepAPI(true, true); } ZenossCredentials credentials = new ZenossCredentials(RhybuddHome.this); mService.API.Login(credentials); tempZenossEvents = mService.API.GetRhybuddEvents(RhybuddHome.this); if (null == tempZenossEvents) { Log.e("Refresh", "We got a null return from the service API, lets try ourselves"); ZenossAPI API; if (settings.getBoolean(ZenossAPI.PREFERENCE_IS_ZAAS, false)) { API = new ZenossAPIZaas(); } else { API = new ZenossAPICore(); } credentials = new ZenossCredentials(RhybuddHome.this); API.Login(credentials); tempZenossEvents = API.GetRhybuddEvents(RhybuddHome.this); } if (tempZenossEvents != null && tempZenossEvents.size() > 0) { retryCount = 0; listOfZenossEvents = tempZenossEvents; handler.sendEmptyMessage(1); RhybuddDataSource datasource = new RhybuddDataSource(RhybuddHome.this); datasource.open(); datasource.UpdateRhybuddEvents(listOfZenossEvents); datasource.close(); try { ZenossAPI.updateLastChecked(RhybuddHome.this); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("RhybuddHome", "Updating last setting", e); } } else if (tempZenossEvents != null && tempZenossEvents.size() == 0) { handler.sendEmptyMessage(50); } else { // TODO Send a proper message handler.sendEmptyMessage(999); } } catch (Exception e) { e.printStackTrace(); BugSenseHandler.sendExceptionMessage("RhybuddHome", "Refresh", e); handler.sendEmptyMessage(999); } } else { Log.e("Refresh", "The service wasn't running for some reason"); dialog.setMessage("The backend service wasn't running.\n\nStarting..."); Intent intent = new Intent(RhybuddHome.this, ZenossPoller.class); startService(intent); retryCount++; doBindService(); if (retryCount > 5) { handler.sendEmptyMessage(999); } else { //handler.sendEmptyMessage(ZenossAPI.HANDLER_REDOREFRESH); handler.sendEmptyMessageDelayed(ZenossAPI.HANDLER_REDOREFRESH, 300); } } } }).start(); } private void finishStart(Boolean firstRun) { list = (ListView) findViewById(R.id.ZenossEventsList); list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); ConfigureHandlers(); //In certain cases it's perfectly safe to rely that the DB is up to date. if (settings.getBoolean("AllowBackgroundService", false) || getIntent().getBooleanExtra("forceRefresh", false) == false || (!regId.equals("") && !settings.getString(ZenossAPI.PREFERENCE_PUSHKEY, "").equals(""))) { Log.i("RhybuddHome", "Background polling is enabled OR we are GCM enabled AND we haven't been asked to force a refresh so we're safe to query the DB"); DBGetThread(); } else { Log.i("RhybuddHome", "Doing a direct call to the API"); Refresh(); } } private void ConfigureHandlers() { handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 0) { try { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } } catch (NullPointerException npe) { //Sigh } try { ((ProgressBar) findViewById(R.id.backgroundWorkingProgressBar)).setVisibility(4); } catch (NullPointerException npe) { //Sigh } OnClickListener listener = new OnClickListener() { public void onClick(View v) { try { //Check if we are in a big layout FrameLayout EventDetailsFragmentHolder = (FrameLayout) findViewById( R.id.EventDetailsFragment); if (EventDetailsFragmentHolder == null) { ManageEvent(v.getTag(R.id.EVENTID).toString(), (Integer) v.getTag(R.id.EVENTPOSITIONINLIST), v.getId()); } else { LoadEventDetailsFragment((Integer) v.getTag(R.id.EVENTPOSITIONINLIST)); } } catch (Exception e) { Toast.makeText(getApplicationContext(), "There was an internal error. A report has been sent.", Toast.LENGTH_SHORT) .show(); //BugSenseHandler.log("EventListOnclick", e); } } }; OnLongClickListener listenerLong = new OnLongClickListener() { public boolean onLongClick(View v) { try { selectForCAB((Integer) v.getTag(R.id.EVENTPOSITIONINLIST)); } catch (Exception e) { Toast.makeText(getApplicationContext(), "There was an internal error. A report has been sent.", Toast.LENGTH_SHORT) .show(); //BugSenseHandler.log("RhybuddHome-onDestroy", e); } return true; } }; OnClickListener addCAB = new OnClickListener() { public void onClick(View v) { try { addToCAB((Integer) v.getTag(R.id.EVENTPOSITIONINLIST)); } catch (Exception e) { Toast.makeText(getApplicationContext(), "There was an internal error. A report has been sent.", Toast.LENGTH_SHORT) .show(); //BugSenseHandler.log("RhybuddHome-onDestroy", e); } } }; //adapter = new ZenossEventsAdaptor(RhybuddHome.this, listOfZenossEvents,listener,listenerLong,addCAB); list.setAdapter(adapter); } else if (msg.what == 1) { try { if (dialog != null && dialog.isShowing()) dialog.setMessage("Refresh Complete!"); } catch (NullPointerException npe) { //Sigh } this.sendEmptyMessageDelayed(0, 1000); } else if (msg.what == 2) { if (dialog != null && dialog.isShowing()) { dialog.setMessage("DB Cache incomplete.\r\nQuerying Zenoss directly.\r\nPlease wait...."); } else { dialog = new ProgressDialog(RhybuddHome.this); dialog.setMessage("DB Cache incomplete.\r\nQuerying Zenoss directly.\r\nPlease wait...."); dialog.setCancelable(false); dialog.show(); } } else if (msg.what == 50) { if (dialog != null && dialog.isShowing()) dialog.dismiss(); try { if (listOfZenossEvents != null) listOfZenossEvents.clear(); if (adapter != null) adapter.notifyDataSetChanged(); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("RhybuddHome", "handler-50", e); } Toast.makeText(RhybuddHome.this, "There are no events to display", Toast.LENGTH_LONG).show(); } else if (msg.what == 3 || msg.what == 999) { if (dialog != null && dialog.isShowing()) dialog.dismiss(); AlertDialog.Builder builder = new AlertDialog.Builder(RhybuddHome.this); builder.setMessage("An error was encountered. Please check your settings and try again.") .setCancelable(false) .setPositiveButton("Edit Settings", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Intent SettingsIntent = new Intent(RhybuddHome.this, SettingsFragment.class); startActivityForResult(SettingsIntent, 99); alertDialog.cancel(); } }).setNegativeButton("Close", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { alertDialog.cancel(); } }); alertDialog = builder.create(); if (!isFinishing()) { try { alertDialog.show(); } catch (Exception e) { //BugSenseHandler.log("alertDialog", e); } } } else if (msg.what == ZenossAPI.HANDLER_REDOREFRESH) { Refresh(); } else { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } Toast.makeText(RhybuddHome.this, "Timed out communicating with host. Please check protocol, hostname and port.", Toast.LENGTH_LONG).show(); } } }; AckEventHandler = new Handler() { public void handleMessage(Message msg) { try { if (msg.what == 0) { if (adapter != null) adapter.notifyDataSetChanged(); } else if (msg.what == 1) { for (ZenossEvent evt : listOfZenossEvents) { if (!evt.getEventState().equals("Acknowledged") && evt.getProgress()) { evt.setProgress(false); evt.setAcknowledged(); } } RhybuddDataSource datasource = null; try { //TODO maybe do this with the bunch of ack id's we have in the thread? datasource = new RhybuddDataSource(RhybuddHome.this); datasource.open(); datasource.UpdateRhybuddEvents(listOfZenossEvents); } catch (Exception e) { e.printStackTrace(); BugSenseHandler.sendExceptionMessage("RhybuddHome", "AckEventsHandler", e); } finally { if (null != datasource) datasource.close(); } if (adapter != null) adapter.notifyDataSetChanged(); } else if (msg.what == 2) { for (Integer i : selectedEvents) { if (listOfZenossEvents.get(i).getProgress()) { listOfZenossEvents.get(i).setProgress(false); listOfZenossEvents.get(i).setAcknowledged(); } } if (adapter != null) adapter.notifyDataSetChanged(); } else if (msg.what == 99) { for (ZenossEvent evt : listOfZenossEvents) { if (!evt.getEventState().equals("Acknowledged") && evt.getProgress()) { evt.setProgress(false); } } if (adapter != null) adapter.notifyDataSetChanged(); Toast.makeText(getApplicationContext(), "There was an error trying to ACK those events.", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "There was an error trying to ACK that event.", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { //BugSenseHandler.log("AckEventsHandler", e); } } }; } public void selectForCAB(int id) { if (listOfZenossEvents.get(id).isSelected()) { selectedEvents.remove(id); listOfZenossEvents.get(id).SetSelected(false); } else { selectedEvents.add(id); listOfZenossEvents.get(id).SetSelected(true); } adapter.notifyDataSetChanged(); mActionMode = startActionMode(mActionModeCallback); } /** * Starts a Contextual Action Bar or adds to the array of items * to be processed by the CAB * @param id The position in the listOfZenossEvents / listview */ public void addToCAB(int id) { if (selectedEvents.contains(id)) { try { selectedEvents.remove(id); listOfZenossEvents.get(id).SetSelected(false); adapter.notifyDataSetChanged(); mActionMode.setTitle("Manage " + selectedEvents.size() + " Events"); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("RhybuddHome", "addToCAB", e); } } else { try { if (mActionMode != null) { selectedEvents.add(id); listOfZenossEvents.get(id).SetSelected(true); adapter.notifyDataSetChanged(); mActionMode.setTitle("Manage " + selectedEvents.size() + " Events"); } else { selectedEvents.add(id); listOfZenossEvents.get(id).SetSelected(true); adapter.notifyDataSetChanged(); mActionMode = startActionMode(mActionModeCallback); } } catch (Exception e) { BugSenseHandler.sendExceptionMessage("RhybuddHome", "addToCAB", e); } } } private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.events_cab, menu); mode.setTitle("Manage " + selectedEvents.size() + " Events"); mode.setSubtitle("Select multiple events for mass acknowledgement"); return true; } // Called each time the action mode is shown. Always called after onCreateActionMode, but // may be called multiple times if the mode is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done } // Called when the user selects a contextual menu item @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.Acknowledge: { final List<String> EventIDs = new ArrayList<String>(); for (final Integer i : selectedEvents) { listOfZenossEvents.get(i).setProgress(true); EventIDs.add(listOfZenossEvents.get(i).getEVID()); } AckEventHandler.sendEmptyMessage(0); AckEvent = new Thread() { public void run() { try { ZenossAPIv2 ackEventAPI; /*if(settings.getBoolean("httpBasicAuth", false)) { ackEventAPI = new ZenossAPIv2(settings.getString("userName", ""), settings.getString("passWord", ""), settings.getString("URL", ""),settings.getString("BAUser", ""), settings.getString("BAPassword", "")); } else { ackEventAPI = new ZenossAPIv2(settings.getString("userName", ""), settings.getString("passWord", ""), settings.getString("URL", "")); } ackEventAPI.AcknowledgeEvents(EventIDs);//ackEventAPI*/ //TODO Check it actually succeeded AckEventHandler.sendEmptyMessage(2); } catch (Exception e) { //BugSenseHandler.log("CABAcknowledge", e); e.printStackTrace(); AckEventHandler.sendEmptyMessage(99); } } }; AckEvent.start(); return true; } case R.id.escalate: { Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("text/plain"); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); // Add data to the intent, the receiving app will decide what to do with it. intent.putExtra(Intent.EXTRA_SUBJECT, "Escalation of " + selectedEvents.size() + " Zenoss Events"); String Events = "Escalated events;\r\n\r\n"; for (Integer i : selectedEvents) { Events += listOfZenossEvents.get(i).getDevice() + " - " + listOfZenossEvents.get(i).getSummary() + "\r\n\r\n"; //list.setItemChecked(i, false); } intent.putExtra(Intent.EXTRA_TEXT, Events); startActivity(Intent.createChooser(intent, "How would you like to escalate these events?")); return true; } default: { for (Integer i : selectedEvents) { listOfZenossEvents.get(i).SetSelected(false); //list.setItemChecked(i, false); } selectedEvents.clear(); adapter.notifyDataSetChanged(); return false; } } } // Called when the user exits the action mode @Override public void onDestroyActionMode(ActionMode mode) { for (Integer i : selectedEvents) { listOfZenossEvents.get(i).SetSelected(false); //list.setItemChecked(i, false); } selectedEvents.clear(); adapter.notifyDataSetChanged(); mActionMode = null; } }; public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.home_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } switch (item.getItemId()) { case R.id.settings: { Intent SettingsIntent = new Intent(RhybuddHome.this, SettingsFragment.class); this.startActivityForResult(SettingsIntent, 99); return true; } /*case R.id.pushconfig: { Intent PushSettingsIntent = new Intent(RhybuddHome.this, PushConfigActivity.class); this.startActivityForResult(PushSettingsIntent, ZenossAPI.ACTIVITYRESULT_PUSHCONFIG); return true; }*/ /*case R.id.Help: { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse("http://wiki.zenoss.org/index.php?title=Rhybudd#Getting_Started")); startActivity(i); return true; }*/ case R.id.devices: { Intent DeviceList = new Intent(RhybuddHome.this, ViewZenossDeviceListActivity.class); RhybuddHome.this.startActivityForResult(DeviceList, 20); return true; } case R.id.search: { onSearchRequested(); return true; } /*case R.id.cache: { Intent MangeDBIntent = new Intent(RhybuddHome.this, ManageDatabase.class); RhybuddHome.this.startActivity(MangeDBIntent); return true; }*/ case R.id.resolveall: { final List<String> EventIDs = new ArrayList<String>(); for (ZenossEvent evt : listOfZenossEvents) { if (!evt.getEventState().equals("Acknowledged")) { evt.setProgress(true); AckEventHandler.sendEmptyMessage(0); EventIDs.add(evt.getEVID()); } } AckEventHandler.sendEmptyMessage(0); AckEvent = new Thread() { public void run() { try { /* ZenossAPIv2 ackEventAPI; if(settings.getBoolean("httpBasicAuth", false)) { ackEventAPI = new ZenossAPIv2(settings.getString("userName", ""), settings.getString("passWord", ""), settings.getString("URL", ""),settings.getString("BAUser", ""), settings.getString("BAPassword", "")); } else { ackEventAPI = new ZenossAPIv2(settings.getString("userName", ""), settings.getString("passWord", ""), settings.getString("URL", "")); } ackEventAPI.AcknowledgeEvents(EventIDs);//ackEventAPI */ //TODO Check it actually succeeded AckEventHandler.sendEmptyMessage(1); } catch (Exception e) { e.printStackTrace(); AckEventHandler.sendEmptyMessage(99); } } }; AckEvent.start(); return true; } case R.id.refresh: { Refresh(); return true; } case R.id.escalate: { Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("text/plain"); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); // Add data to the intent, the receiving app will decide what to do with it. intent.putExtra(Intent.EXTRA_SUBJECT, "Escalation of Zenoss Events"); String Events = ""; for (ZenossEvent evt : listOfZenossEvents) { Events += evt.getDevice() + " - " + evt.getSummary() + "\r\n\r\n"; } intent.putExtra(Intent.EXTRA_TEXT, Events); startActivity(Intent.createChooser(intent, "How would you like to escalate these events?")); } } return false; } private void doGCMRegistration(final String PushKey) { //TODO check for freshness so as to not waste too much data / bandwidth on every resume! if (!PushKey.equals("")) { GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("")) { //Log.e("GCM", "Registering"); GCMRegistrar.register(this, ZenossAPI.SENDER_ID); } else { //Log.e("GCM", "Already registered"); } ((Thread) new Thread() { public void run() { if (!ZenossAPI.registerPushKey(PushKey, regId, ZenossAPI .md5(Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)))) { runOnUiThread(new Runnable() { public void run() { Toast.makeText(RhybuddHome.this, getResources().getString(R.string.ErrorRegisterGCM), Toast.LENGTH_LONG) .show(); } }); } } }).start(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //Forces our onResume() function to do a DB call rather than a full HTTP request just cos we returned //from one of our subscreens resumeOnResultPollAPI = false; BackupManager bm = new BackupManager(this); //Check what the result was from the Settings Activity if (requestCode == 99) { //Refresh the settings settings = PreferenceManager.getDefaultSharedPreferences(this); Intent intent = new Intent(this, ZenossPoller.class); intent.putExtra("settingsUpdate", true); startService(intent); bm.dataChanged(); } else if (requestCode == ZenossAPI.ACTIVITYRESULT_PUSHCONFIG) { if (null != data && data.hasExtra(ZenossAPI.PREFERENCE_PUSHKEY)) { doGCMRegistration(data.getStringExtra(ZenossAPI.PREFERENCE_PUSHKEY)); } } else { //In theory the Settings activity should perform validation and only finish() if the settings pass validation if (resultCode == 1) { SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("FirstRun", false); editor.commit(); //Also update our onResume helper bool although it should already be set firstRun = false; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage( "Additional settings and functionality can be found by pressing the action bar overflow (or pressing the menu button).\r\n" + "\r\nPlease note that this is app is still in Beta. If you experience issues please email;\r\nGareth@NetworksAreMadeOfString.co.uk") .setTitle("Welcome to Rhybudd!").setCancelable(false) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finishStart(true); } }); AlertDialog welcomeDialog = builder.create(); try { welcomeDialog.show(); } catch (Exception e) { finishStart(true); } bm.dataChanged(); } else if (resultCode == 2) { Toast.makeText(RhybuddHome.this, getResources().getString(R.string.FirstRunNeedSettings), Toast.LENGTH_LONG).show(); finish(); } //Who knows what happened here - quit else { Toast.makeText(RhybuddHome.this, getResources().getString(R.string.FirstRunNeedSettings), Toast.LENGTH_LONG).show(); finish(); } } } public void LoadEventDetailsFragment(int Position) { listOfZenossEvents.get(selectedFragmentEvent).setFragmentDisplay(false); listOfZenossEvents.get(Position).setFragmentDisplay(true); selectedFragmentEvent = Position; adapter.notifyDataSetChanged(); fragmentManager = getSupportFragmentManager(); fragmentTransaction = fragmentManager.beginTransaction(); Fragment fragment = new ViewEventFragment(); Bundle args = new Bundle(); args.putInt("Position", Position); args.putString("Device", listOfZenossEvents.get(Position).getDevice()); args.putString("Component", listOfZenossEvents.get(Position).getComponentText()); args.putString("EventClass", listOfZenossEvents.get(Position).geteventClass()); args.putString("Summary", listOfZenossEvents.get(Position).getSummary()); args.putString("FirstSeen", listOfZenossEvents.get(Position).getfirstTime()); args.putString("LastSeen", listOfZenossEvents.get(Position).getlastTime()); args.putInt("EventCount", listOfZenossEvents.get(Position).getCount()); fragment.setArguments(args); fragmentTransaction.replace(R.id.EventDetailsFragment, fragment); fragmentTransaction.commit(); ((FrameLayout) findViewById(R.id.EventDetailsFragment)).setVisibility(View.VISIBLE); //((View) findViewById(R.id.fragmentIndicator)).setVisibility(View.VISIBLE); FragmentVisible = true; } public void ManageEvent(final String EventID, final int Position, final int viewID) { AlertDialog.Builder alertbox = new AlertDialog.Builder(this); alertbox.setMessage("What would you like to do?"); alertbox.setPositiveButton("Ack Event", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { AcknowledgeSingleEvent(Position); } }); alertbox.setNeutralButton("View Event", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { /*Intent ViewEventIntent = new Intent(RhybuddHome.this, ViewZenossEvent.class); try { ViewEventIntent.putExtra("EventID", EventID); ViewEventIntent.putExtra("Count", listOfZenossEvents.get(Position).getCount()); ViewEventIntent.putExtra("Device", listOfZenossEvents.get(Position).getDevice()); ViewEventIntent.putExtra("EventState", listOfZenossEvents.get(Position).getEventState()); ViewEventIntent.putExtra("FirstTime", listOfZenossEvents.get(Position).getfirstTime()); ViewEventIntent.putExtra("LastTime", listOfZenossEvents.get(Position).getlastTime()); ViewEventIntent.putExtra("Severity", listOfZenossEvents.get(Position).getSeverity()); ViewEventIntent.putExtra("Summary", listOfZenossEvents.get(Position).getSummary()); } catch(Exception e) { } RhybuddHome.this.startActivity(ViewEventIntent);*/ Intent ViewEventIntent = new Intent(RhybuddHome.this, ViewZenossEventActivity.class); ViewEventIntent.putExtra("EventID", EventID); ArrayList<String> EventNames = new ArrayList<String>(); ArrayList<String> EVIDs = new ArrayList<String>(); for (ZenossEvent evt : listOfZenossEvents) { EventNames.add(evt.getDevice()); EVIDs.add(evt.getEVID()); } ViewEventIntent.putStringArrayListExtra("eventnames", EventNames); ViewEventIntent.putStringArrayListExtra("evids", EVIDs); RhybuddHome.this.startActivityForResult(ViewEventIntent, 20); } }); alertbox.setNegativeButton("Nothing", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { } }); alertbox.show(); } public void AcknowledgeSingleEvent(final int Position) { listOfZenossEvents.get(Position).setProgress(true); AckEventHandler.sendEmptyMessage(0); AckEvent = new Thread() { public void run() { try { //TODO This needs moving to the new API model /*ZenossAPIv2 ackEventAPI = new ZenossAPIv2(settings.getString("userName", ""), settings.getString("passWord", ""), settings.getString("URL", "")); ackEventAPI.AcknowledgeEvent(listOfZenossEvents.get(Position).getEVID());//ackEventAPI*/ listOfZenossEvents.get(Position).setProgress(false); listOfZenossEvents.get(Position).setAcknowledged(); AckEventHandler.sendEmptyMessage(1); } catch (Exception e) { e.printStackTrace(); BugSenseHandler.sendExceptionMessage("RhybuddHome", "AcknowledgeSingleEvent", e); AckEventHandler.sendEmptyMessage(99); } } }; AckEvent.start(); } @Override public void onBackPressed() { if (FragmentVisible) { try { ((FrameLayout) findViewById(R.id.EventDetailsFragment)).setVisibility(View.GONE); //((View) findViewById(R.id.fragmentIndicator)).setVisibility(View.GONE); listOfZenossEvents.get(selectedFragmentEvent).setFragmentDisplay(false); selectedFragmentEvent = 0; adapter.notifyDataSetChanged(); } catch (Exception e) { super.onBackPressed(); } FragmentVisible = false; } else { super.onBackPressed(); } } //------------------------------------------------------------------// // // // Connection to the the ZenossPoller Service // // // //------------------------------------------------------------------// void doUnbindService() { if (mBound) { // Detach our existing connection. unbindService(mConnection); mBound = false; } } void doBindService() { bindService(new Intent(this, ZenossPoller.class), mConnection, Context.BIND_AUTO_CREATE); mBound = true; } @Override protected void onPause() { super.onPause(); // Unbind from the service doUnbindService(); } private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance ZenossPoller.LocalBinder binder = (ZenossPoller.LocalBinder) service; mService = binder.getService(); mBound = true; //Toast.makeText(RhybuddHome.this, "Connected to Service", Toast.LENGTH_SHORT).show(); } @Override public void onServiceDisconnected(ComponentName arg0) { //Toast.makeText(RhybuddHome.this, "Disconnected to Service", Toast.LENGTH_SHORT).show(); mBound = false; } }; }