Java tutorial
/* Copyright 2013, 2014 joshua.tee@gmail.com This file is part of wX. wX 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. wX 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 wX. If not, see <http://www.gnu.org/licenses/>. */ package joshuatee.wx; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.annotation.SuppressLint; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.text.Html; import android.util.TypedValue; import android.view.ContextMenu; import android.view.Gravity; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.ContextMenu.ContextMenuInfo; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.ScrollView; import android.widget.TableLayout; import android.widget.TextView; @SuppressLint("UseSparseArrays") public class NEXRADAttributesActivity extends CommonActionBarFragment { // provides nexrad storm attributes, navigation drawer to filter by state // select entry to visit nexrad interface // long press on entry to save as location String alert_cod_radar_current = ""; int highlight_color = Color.YELLOW; int background_color = Color.WHITE; String highlight_color_str = "yellow"; String background_color_str = "white"; final int dbz_highlight = 59; final double hail_highlight = 1.00; Map<String, Integer> map_state = new TreeMap<String, Integer>(); Map<String, Integer> map_state_dbz = new TreeMap<String, Integer>(); Map<Integer, String> map_button_state = new HashMap<Integer, String>(); Map<Integer, String> map_button_county = new HashMap<Integer, String>(); private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; String[] state_array = new String[] {}; String[] state_array_label; boolean first_run = true; String filter = "All"; String dataAsString = ""; final String url = "http://www.wunderground.com/weather-radar"; int padding; int padding_vertical; float text_size; Pattern comma; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); preferences = PreferenceManager.getDefaultSharedPreferences(this); theme_blue_current = preferences.getString("THEME_BLUE", ""); if (theme_blue_current.contains("white")) { highlight_color = Color.BLUE; background_color = Color.BLACK; highlight_color_str = "blue"; background_color_str = "black"; } setTheme(Utility.Theme(theme_blue_current)); setContentView(R.layout.activity_nexradattributes); Resources res = getResources(); comma = Pattern.compile(","); padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) res.getDimension(R.dimen.padding), getResources().getDisplayMetrics()); padding_vertical = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) res.getDimension(R.dimen.padding_vertical), getResources().getDisplayMetrics()); text_size = res.getDimension(R.dimen.listitem_text); alert_cod_radar_current = preferences.getString("ALERT_COD_RADAR", ""); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer); mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, state_array)); mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.drawer, R.string.drawer_open, R.string.drawer_close) { public void onDrawerClosed(View view) { super.onDrawerClosed(view); } public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); new GetContent().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } protected void onRestart() { alert_cod_radar_current = preferences.getString("ALERT_COD_RADAR", ""); super.onRestart(); } private class GetContent extends AsyncTask<String, String, String> { String nexrad_attr_html = ""; @Override protected String doInBackground(String... params) { try { if (dataAsString.equals("") || filter.equals("All")) { dataAsString = Utility.GetStringFromURL(url); } Pattern p3 = Pattern.compile("Doppler Radar Detected Storms(.*)Tornado Vortex Signature"); // inline-list radar-key / Matcher m3 = p3.matcher(dataAsString); String name1 = ""; while (m3.find()) { name1 = m3.group(1); } //String nexrad_attr_html2 = name1.replace("/radar/radblast","http://www.wunderground.com/radar/radblast"); nexrad_attr_html = name1.replace("/radar/radblast", "http://www.wunderground.com/radar/radblast") .replace("<li class=\"b\">", ""); } catch (Exception e) { } return "Executed"; } @Override protected void onPostExecute(String result) { TableLayout dynamicview = (TableLayout) findViewById(R.id.tl); dynamicview.removeAllViews(); map_state.clear(); TextView tv_1 = new TextView(getBaseContext(), null, android.R.attr.borderlessButtonStyle); tv_1.setGravity(Gravity.LEFT); tv_1.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_size); tv_1.setPadding(padding, padding_vertical, padding, padding_vertical); tv_1.setTextColor(background_color); tv_1.setId(0); dynamicview.addView(tv_1); tv_1.setOnClickListener(new OnClickListener() { public void onClick(View v) { filter = "All"; new GetContent().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } }); int total_storms = 0; String county = ""; String state = ""; String br = ""; String eet = ""; String vil = ""; String ch1 = ""; String ch2 = ""; String size_hail = ""; String speed = ""; String direction = ""; String rid = ""; String state1 = ""; String rid_location = ""; Integer freq3 = 0; Pattern p3; Matcher m3; int current_dbz = 0; int max_dbz = 0; double size_hail_num = 0.0; StringBuilder sb = new StringBuilder(100); Pattern p2 = Pattern.compile( "<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?"); p3 = Pattern.compile("ID=([A-Z]{3})"); try { Pattern p = Pattern.compile("<tr>(.*?)</tr>"); Matcher m = p.matcher(nexrad_attr_html); Matcher m2; TextView tv_tmp; while (m.find()) { m2 = p2.matcher(m.group(1)); while (m2.find()) { county = m2.group(2); state = m2.group(3); br = m2.group(4); eet = m2.group(5); vil = m2.group(6); ch1 = m2.group(7); ch2 = m2.group(8); size_hail = m2.group(9); speed = m2.group(10); direction = m2.group(11); m3 = p3.matcher(county); m3.find(); rid = m3.group(1); state = state.replaceAll("<a href.*?>", ""); state = state.replace("</a>", ""); county = county.replaceAll("<a href.*?>", ""); county = county.replace("</a>", ""); vil = vil.replace("&sup", ""); rid_location = preferences.getString("RID_LOC_" + rid, "unk,unk"); state = comma.split(rid_location)[0]; state1 = state; freq3 = map_state.get(state1); map_state.put(state1, (freq3 == null) ? 1 : freq3 + 1); map_button_county.put(total_storms + 1, county); map_button_state.put(total_storms + 1, state); if (filter.equals("All") || state.equals(filter)) { tv_tmp = new TextView(getBaseContext(), null, android.R.attr.borderlessButtonStyle); tv_tmp.setGravity(Gravity.LEFT); tv_tmp.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_size); tv_tmp.setPadding(padding, padding_vertical, padding, padding_vertical); tv_tmp.setTextColor(background_color); tv_tmp.setId(total_storms + 1); registerForContextMenu(tv_tmp); try { current_dbz = Integer.parseInt(br.replace(" dBZ", "")); max_dbz = 0; if (map_state_dbz.get(state1) == null) { map_state_dbz.put(state1, current_dbz); } else { max_dbz = map_state_dbz.get(state1); if ((current_dbz > max_dbz)) { map_state_dbz.put(state1, current_dbz); } } if (current_dbz > dbz_highlight) { br = "<font color=" + highlight_color_str + ">" + br + "</font>"; } if (m.group(1).contains("storm-type tornado")) { br = "<font color=" + "red" + ">" + br + "</font>"; } size_hail_num = Double.parseDouble(size_hail.replace(" in.", "")); if (size_hail_num >= hail_highlight) { size_hail = "<font color=" + highlight_color_str + ">" + size_hail + "</font>"; } } catch (Exception e) { } sb.setLength(0); sb.append(br); sb.append(" <font color="); sb.append(highlight_color_str); sb.append(">"); sb.append(state); sb.append(", "); sb.append(county); sb.append(" </font>"); sb.append(eet); sb.append(" "); sb.append(vil); sb.append(" "); sb.append(ch1); sb.append(" "); sb.append(ch2); sb.append(" "); sb.append(size_hail); sb.append(" "); sb.append(speed); sb.append(" "); sb.append(direction); tv_tmp.append(Html.fromHtml(sb.toString())); final String RID = rid; final String STATE = state; tv_tmp.setOnClickListener(new OnClickListener() { public void onClick(View v) { intent = new Intent(getBaseContext(), UtilityUSImg.getRadarClass(preferences)); intent.putExtra(UtilityUSImg.getRadarClassExtra(preferences), new String[] { RID, STATE }); startActivity(intent); } }); dynamicview.addView(tv_tmp); } total_storms++; } } String map_out = map_state.toString().replaceAll("\\{|\\}", ""); tv_1.setText( Html.fromHtml("<br><b>" + map_out + System.getProperty("line.separator") + "</b><br>")); } catch (Exception e) { } if (filter.equals("All")) { setTitle("(" + total_storms + ") NEXRAD Attributes"); } else { setTitle("(" + map_state.get(filter) + ") " + filter + " NEXRAD Attributes"); } if (first_run) { Object[] obj = map_state.keySet().toArray(); state_array = Arrays.copyOf(obj, obj.length, String[].class); state_array_label = Arrays.copyOf(state_array, state_array.length, String[].class); int j = 0; for (j = 0; j < state_array_label.length; j++) { state_array_label[j] = state_array_label[j] + ": " + map_state.get(state_array[j]) + " max: " + map_state_dbz.get(state_array[j]) + "dBZ"; } mDrawerList.setAdapter( new ArrayAdapter<String>(getBaseContext(), R.layout.drawer_list_item, state_array_label)); first_run = false; } setProgressBarIndeterminateVisibility(false); } @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); ScrollView sv = (ScrollView) findViewById(R.id.sv); sv.smoothScrollTo(0, 0); } @Override protected void onProgressUpdate(String... values) { } } private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectItem(position); } } private void selectItem(int position) { mDrawerList.setItemChecked(position, false); mDrawerLayout.closeDrawer(mDrawerList); filter = state_array[position]; new GetContent().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); String county = map_button_county.get(v.getId()); String state = map_button_state.get(v.getId()); menu.add(0, v.getId(), 0, "Add new location for " + county + ", " + state); } @Override public boolean onContextItemSelected(MenuItem item) { if (((String) item.getTitle()).contains("Add new location for ")) { LocationAdd(item.getItemId()); } else { return false; } return true; } public void LocationAdd(int id) { new SaveLocFromCounty().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, id); } private class SaveLocFromCounty extends AsyncTask<Integer, String, String> { String toast_str = ""; String[] coord; @Override protected String doInBackground(Integer... params) { String loc_num_to_save_str = ""; int loc_num_int_current = preferences.getInt("LOC_NUM_INT", -1); loc_num_int_current++; loc_num_to_save_str = Integer.toString(loc_num_int_current); String state = map_button_state.get(params[0]); String county = map_button_county.get(params[0]); coord = UtilityLocation.GetXYFromAddressOSM(county + "," + state); String x = coord[0]; String y = coord[1]; toast_str = UtilityLocation.LocationSave(getBaseContext(), loc_num_to_save_str, x, y, state + "_" + county); return "Executed"; } @Override protected void onPostExecute(String result) { Utility.MakeToast(getBaseContext(), toast_str); setProgressBarIndeterminateVisibility(false); } @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); } @Override protected void onProgressUpdate(String... values) { } } }