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.Calendar; import java.util.Locale; import java.util.Map; import java.util.TreeMap; import java.util.regex.Pattern; import joshuatee.wx.R; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.app.DatePickerDialog; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.LayerDrawable; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.text.Html; import android.util.DisplayMetrics; 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.DatePicker; import android.widget.ListView; import android.widget.ScrollView; import android.widget.TableLayout; import android.widget.TextView; public class StormReportsActivity extends CommonActionBarFragment { // SPC storm reports. Touch image for data selector public static final String NO = ""; String no = ""; DisplayMetrics dm; String img_url = ""; String text_url = ""; String iowa_meso_url = ""; String iowa_meso_str = ""; Map<String, Integer> map_state = new TreeMap<String, Integer>(); String html_color = "blue"; String[] wfo_arr; String[] x_arr; String[] y_arr; String[] time_arr; String date = ""; String month_str = ""; String day_str = ""; String year_str = ""; private int pYear; private int pMonth; private int pDay; private int cYear; private int cMonth; private int cDay; int highlight_color = Color.YELLOW; int background_color = Color.WHITE; String highlight_color_str = "yellow"; String background_color_str = "white"; TextView[] tv_arr = new TextView[0]; 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 sig_html_tmp = ""; String text = ""; Bitmap bitmap; TouchImageView2 iv; int array_length; int padding; int padding_vertical; float text_size; Pattern comma; Pattern br; int k = 0; int storm_cnt = 0; StringBuilder output; String output_str; String[] text_arr; String state1; Integer freq3; @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_storm_reports); //padding = (int)res.getDimension(R.dimen.padding); //padding_vertical = (int)res.getDimension(R.dimen.padding_vertical); Resources res = getResources(); 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); iv = new TouchImageView2(getBaseContext()); no = getIntent().getStringExtra(NO); dm = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(dm); final Calendar cal = Calendar.getInstance(); pYear = cal.get(Calendar.YEAR); pMonth = cal.get(Calendar.MONTH); pDay = cal.get(Calendar.DAY_OF_MONTH); // FIXME, handle first of the month if (no.equals("yesterday")) pDay--; cYear = pYear; cMonth = pMonth; cDay = pDay; UpdateIowaMesoData(); img_url = "http://www.spc.noaa.gov/climo/reports/" + no + ".gif"; text_url = "http://www.spc.noaa.gov/climo/reports/" + no + ".csv"; comma = Pattern.compile(","); br = Pattern.compile("<br>"); output = new StringBuilder(200); 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); } private class GetContent extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... params) { if (first_run) { text = Utility.GetStringFromURLSep(text_url); bitmap = Utility.getBitmapFromURL(img_url); } return "Executed"; } @Override protected void onPostExecute(String result) { // Time,F_Scale,Location,County,State,Lat,Lon,Comments ( Speed / Size ) text_arr = br.split(text); map_state.clear(); setTitle("Storm Reports - " + no); TableLayout dynamicview = (TableLayout) findViewById(R.id.tl); TableLayout.LayoutParams lprams = new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT); dynamicview.removeAllViews(); dynamicview.addView(iv); iv.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { DatePickerDialog stDatePicker = new DatePickerDialog(StormReportsActivity.this, pDateSetListener, pYear, pMonth, pDay); Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, 2004); // 2011-05-27 was the earliest date for filtered, moved to non-filtered and can go back to 2004-03-23 cal.set(Calendar.MONTH, 2); cal.set(Calendar.DAY_OF_MONTH, 23); stDatePicker.getDatePicker().setMinDate(cal.getTimeInMillis() - 1000); stDatePicker.getDatePicker().setMaxDate(System.currentTimeMillis()); stDatePicker.show(); } }); UtilityImg.ResizeViewSetImg(dm, bitmap, iv); iv.resetZoom(); TextView tv = new TextView(getBaseContext(), null, android.R.attr.borderlessButtonStyle); tv.setGravity(Gravity.LEFT); tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_size); tv.setPadding(padding, padding_vertical, padding, padding_vertical); tv.setTextColor(background_color); dynamicview.addView(tv); tv.setOnClickListener(new OnClickListener() { public void onClick(View v) { filter = "All"; new GetContent().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } }); tv_arr = new TextView[text_arr.length + 1]; wfo_arr = new String[text_arr.length]; x_arr = new String[text_arr.length]; y_arr = new String[text_arr.length]; time_arr = new String[text_arr.length]; String x = ""; String y = ""; String state = ""; String[] line_arr; array_length = text_arr.length; for (k = 0; k < array_length; k++) { x = ""; y = ""; //output = ""; output.setLength(0); state = ""; if (text_arr[k].contains(",F_Scale,")) { //output = output + "<H2><font color=" + highlight_color_str + ">Tornado Reports</font></H2>"; output.append("<H2><font color="); output.append(highlight_color_str); output.append(">Tornado Reports</font></H2>"); storm_cnt--; } else if (text_arr[k].contains(",Speed,")) { //output = output + "<H2><font color=" + highlight_color_str + ">Wind Reports</font></H2>"; output.append("<H2><font color="); output.append(highlight_color_str); output.append(">Wind Reports</font></H2>"); storm_cnt--; } else if (text_arr[k].contains(",Size,")) { //output = output + "<H2><font color=" + highlight_color_str + ">Hail Reports</font></H2>"; output.append("<H2><font color="); output.append(highlight_color_str); output.append(">Hail Reports</font></H2>"); storm_cnt--; } else { line_arr = comma.split(text_arr[k]); if (line_arr.length > 7) { /* output = output + line_arr[0] + " " + line_arr[1] + " " + line_arr[2] + "<font color=" + highlight_color_str + ">" + " " + line_arr[3] + " " + line_arr[4] + "</font>" + " " + " " + line_arr[5] + " " + line_arr[6] + "<br>" + "<i>" + line_arr[7] + "</i>"+ "<br>" ;*/ output.append(line_arr[0]); output.append(" "); output.append(line_arr[1]); output.append(" "); output.append(line_arr[2]); output.append("<font color="); output.append(highlight_color_str); output.append("> "); //output.append(" "); output.append(line_arr[3]); output.append(" "); output.append(line_arr[4]); output.append("</font> "); //output.append(" "); output.append(line_arr[5]); output.append(" "); output.append(line_arr[6]); output.append("<br>"); output.append("<i>"); output.append(line_arr[7]); output.append("</i><br>"); // 0 - GMT time // 1 - unit // 2 - address // 3 - City // 4 - State // 5 - X // 6 - Y // 7 - description (WFO) state1 = line_arr[4]; state = state1; freq3 = map_state.get(state1); map_state.put(state1, (freq3 == null) ? 1 : freq3 + 1); x = line_arr[5]; y = line_arr[6]; x_arr[k] = line_arr[5]; y_arr[k] = line_arr[6]; wfo_arr[k] = UtilityString.Parse(line_arr[7], "\\((.*?)\\)"); time_arr[k] = line_arr[0]; } } output_str = output.toString(); if (filter.equals("All") || state.equals(filter) || output_str.contains("<H2>")) { storm_cnt++; tv_arr[k] = new TextView(getApplicationContext(), null, android.R.attr.borderlessButtonStyle); tv_arr[k].setLayoutParams(lprams); tv_arr[k].setGravity(Gravity.LEFT); tv_arr[k].setTextSize(TypedValue.COMPLEX_UNIT_PX, text_size); //tv_arr[k].setPadding(15,3,15,3); tv_arr[k].setPadding(padding, 3, padding, 3); tv_arr[k].setText(Html.fromHtml(output_str)); tv_arr[k].setTextColor(background_color); tv_arr[k].setId(k); if (!output_str.contains("<H2>")) registerForContextMenu(tv_arr[k]); final String x_str = x; final String y_str = y; tv_arr[k].setOnClickListener(new OnClickListener() { public void onClick(View v) { intent = new Intent(getBaseContext(), WebscreenAB.class); intent.putExtra(WebscreenAB.URL, new String[] { UtilityMap.GenMapURL(x_str, y_str, "11"), "wX" }); startActivity(intent); } }); dynamicview.addView(tv_arr[k]); } } String map_out = map_state.toString(); map_out = map_out.replaceAll("\\{|\\}", ""); tv.setText(Html.fromHtml("<br><b>" + map_out + System.getProperty("line.separator") + "</b><br>")); 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]); } mDrawerList.setAdapter( new ArrayAdapter<String>(getBaseContext(), R.layout.drawer_list_item, state_array_label)); first_run = false; } setTitle("(" + Integer.toString(storm_cnt) + ") Storm Reports - " + no); 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 DatePickerDialog.OnDateSetListener pDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { pYear = year; pMonth = monthOfYear; pDay = dayOfMonth; updateDisplay(); } }; private void updateDisplay() { if (cMonth != pMonth || cYear != pYear || cDay != pDay) { UpdateIowaMesoData(); no = date + "_rpts"; img_url = "http://www.spc.noaa.gov/climo/reports/" + no + ".gif"; text_url = "http://www.spc.noaa.gov/climo/reports/" + no + ".csv"; first_run = true; filter = "All"; new GetContent().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); cYear = pYear; cMonth = pMonth; cDay = pDay; } } 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); int index = v.getId(); String x = x_arr[index]; String y = y_arr[index]; String rid1 = UtilityLocation.GetNearestRid(getBaseContext(), x, y); menu.add(0, v.getId(), 0, "Show N0Q from " + rid1); menu.add(0, v.getId(), 0, "Show N0U from " + rid1); menu.add(0, v.getId(), 0, "Show N0Q ( no blue dot )"); menu.add(0, v.getId(), 0, "Show N0U ( no blue dot )"); rid1 = UtilityNexrad.GetTDWRFromRID(rid1); if (!rid1.equals("")) { menu.add(0, v.getId(), 0, "Show TR0 from " + rid1); menu.add(0, v.getId(), 0, "Show TV0 from " + rid1); menu.add(0, v.getId(), 0, "Show TR0 ( no blue dot )"); menu.add(0, v.getId(), 0, "Show TV0 ( no blue dot )"); } } @Override public boolean onContextItemSelected(MenuItem item) { if (((String) item.getTitle()).contains("Show N0Q from")) { RadarProdShow(item.getItemId(), "N0Q", true); } else if (((String) item.getTitle()).contains("Show N0U from")) { RadarProdShow(item.getItemId(), "N0U", true); } else if (((String) item.getTitle()).contains("Show TR0 from")) { RadarProdShow(item.getItemId(), "TR0", true); } else if (((String) item.getTitle()).contains("Show TV0 from")) { RadarProdShow(item.getItemId(), "TV0", true); } else if (item.getTitle().equals("Show N0Q ( no blue dot )")) { RadarProdShow(item.getItemId(), "N0Q", false); } else if (item.getTitle().equals("Show N0U ( no blue dot )")) { RadarProdShow(item.getItemId(), "N0U", false); } else if (item.getTitle().equals("Show TR0 ( no blue dot )")) { RadarProdShow(item.getItemId(), "TR0", false); } else if (item.getTitle().equals("Show TV0 ( no blue dot )")) { RadarProdShow(item.getItemId(), "TV0", false); } else { return false; } return true; } public void RadarProdShow(int id, String prod, Boolean show_dot) { String x = x_arr[id]; String y = y_arr[id]; String time = time_arr[id]; String rid1 = UtilityLocation.GetNearestRid(getBaseContext(), x, y); time = UtilityStringExternal.truncate(time, 3); if (prod.equals("TR0") || prod.equals("TV0")) { rid1 = UtilityNexrad.GetTDWRFromRID(rid1); } // FIXME 6am-6am CST so need to account for DST starting in Nov from 4 to 5 hrs if (Integer.parseInt(time_arr[id]) < 1000) { month_str = String.format(Locale.US, "%02d", pMonth + 1); day_str = String.format(Locale.US, "%02d", pDay + 1); year_str = Integer.toString(pYear); year_str = year_str.substring(2, 4); date = year_str + month_str + day_str; iowa_meso_url = "http://mesonet.agron.iastate.edu/archive/data/20" + year_str + "/" + month_str + "/" + day_str + "/GIS/ridge/"; iowa_meso_str = "20" + year_str + month_str + day_str; } String full_url = iowa_meso_url + rid1 + "/" + prod + "/"; String pattern = rid1 + "_" + prod + "_" + iowa_meso_str + time; // FIXME // implement method to find closest rid like AU if (!show_dot) { x = "0.0"; y = "0.0"; } //Log.i("wx",full_url); new GetImage().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, full_url, pattern, rid1, x, y); } private class GetImage extends AsyncTask<String, String, String> { LayerDrawable ld1; @Override protected String doInBackground(String... params) { String url = params[0]; String match_str = "(" + params[1] + "[0-9]\\.png)"; String rid = params[2]; String x_str = params[3]; String y_str = params[4]; ld1 = UtilityUSImgIOWA.NWSLayeredImgArchived(getBaseContext(), url, match_str, rid, false, x_str, y_str); return "Executed"; } @Override protected void onPostExecute(String result) { UtilityImg.ResizeViewSetLD(dm, ld1, iv); iv.resetZoom(); ScrollView sv = (ScrollView) findViewById(R.id.sv); sv.smoothScrollTo(0, 0); setProgressBarIndeterminateVisibility(false); } @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); } @Override protected void onProgressUpdate(String... values) { } } private void UpdateIowaMesoData() { month_str = String.format(Locale.US, "%02d", pMonth + 1); day_str = String.format(Locale.US, "%02d", pDay); year_str = Integer.toString(pYear); year_str = year_str.substring(2, 4); date = year_str + month_str + day_str; iowa_meso_url = "http://mesonet.agron.iastate.edu/archive/data/20" + year_str + "/" + month_str + "/" + day_str + "/GIS/ridge/"; iowa_meso_str = "20" + year_str + month_str + day_str; } }