Java tutorial
package com.lcl.thumbweather; import android.Manifest; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.Typeface; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.InputType; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.webkit.WebView; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.google.gson.Gson; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.RoundingMode; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.text.DateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import com.google.gson.JsonSyntaxException; import com.lcl.thumbweather.R; /** * Created by Administrator on 2016/5/10. */ public class MainActivity extends AppCompatActivity implements LocationListener { private static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 1; public static final int SHOW_LOCATOIN = 0; public static final int NO_LOCATOIN = 1; private static Map<String, Integer> speedUnits = new HashMap<>(3); private static Map<String, Integer> pressUnits = new HashMap<>(3); Typeface weatherFont; Weather todayWeather = new Weather(); TextView todayTemperature; TextView todayDescription; TextView todayWind; TextView todayPressure; TextView todayHumidity; TextView todaySunrise; TextView todaySunset; // TextView todayMaxTemper; // TextView todayMinTemper; TextView todayIcon; TextView cityIs; ViewPager viewPager; TabLayout tabLayout; View appView; ProgressDialog progressDialog; int loading = 0; boolean darkTheme; boolean destroyed = false; private List<Weather> longTermWeather; private List<Weather> longTermTodayWeather; private List<Weather> longTermTomorrowWeather; private List<Weather> longTemper; private List<Temper> temperToday = new ArrayList<>(); private List<Temper> temperTomorrow = new ArrayList<>(); private List<Temper> temperLater = new ArrayList<>(); private List<Temper> temperLater1 = new ArrayList<>(); private List<Temper> temperLater2 = new ArrayList<>(); private String recentCity = ""; private ArrayList temper; private static void close(Closeable x) { try { if (x != null) { x.close(); } } catch (IOException e) { Log.e("IOException Data", "Error occurred while closing stream"); } } @Override protected void onCreate(Bundle savedInstanceState) { Log.e("-LCL-", "MainActivity:onCreated."); // Initialize the associated SharedPreferences file with default values PreferenceManager.setDefaultValues(this, R.xml.prefs, false); darkTheme = false; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); if (prefs.getBoolean("darkTheme", false)) { setTheme(R.style.AppTheme_NoActionBar_Dark); darkTheme = true; } // ? activity super.onCreate(savedInstanceState); setContentView(R.layout.activity_scrolling); appView = findViewById(R.id.viewApp); progressDialog = new ProgressDialog(MainActivity.this); // toolbar Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); // toolbar.setTitle(""); setSupportActionBar(toolbar); //Logo toolbar.setLogo(R.mipmap.umbrella_white); if (darkTheme) { toolbar.setPopupTheme(R.style.AppTheme_PopupOverlay_Dark); } // ? textboxes todayTemperature = (TextView) findViewById(R.id.todayTemperature); todayDescription = (TextView) findViewById(R.id.todayDescription); todayWind = (TextView) findViewById(R.id.todayWind); todayPressure = (TextView) findViewById(R.id.todayPressure); todayHumidity = (TextView) findViewById(R.id.todayHumidity); todaySunrise = (TextView) findViewById(R.id.todaySunrise); todaySunset = (TextView) findViewById(R.id.todaySunset); todayIcon = (TextView) findViewById(R.id.todayIcon); cityIs = (TextView) findViewById(R.id.city); weatherFont = Typeface.createFromAsset(this.getAssets(), "fonts/weather.ttf"); todayIcon.setTypeface(weatherFont); // ? viewPager viewPager = (ViewPager) findViewById(R.id.viewPager); tabLayout = (TabLayout) findViewById(R.id.tabs); destroyed = false; initMappings(); // ? preloadWeather(); // AlarmReceiver.setRecurringAlarm(this); } public WeatherRecyclerAdapter getAdapter(int id) { Log.e("188-LCL-", "WeatherRecyclerAdapter:getAdapter"); WeatherRecyclerAdapter weatherRecyclerAdapter; if (id == 0) { weatherRecyclerAdapter = new WeatherRecyclerAdapter(this, longTermTodayWeather); } else if (id == 1) { weatherRecyclerAdapter = new WeatherRecyclerAdapter(this, longTermTomorrowWeather); } else { weatherRecyclerAdapter = new WeatherRecyclerAdapter(this, longTermWeather); } return weatherRecyclerAdapter; } @Override public void onResume() { Log.e("-LCL-", "onResume"); super.onResume(); boolean darkTheme = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("darkTheme", false); if (darkTheme != this.darkTheme) { // Restart activity to apply theme overridePendingTransition(0, 0); finish(); overridePendingTransition(0, 0); startActivity(getIntent()); } else if (isNetworkAvailable()) { getTodayWeather(); getLongTermWeather(); } } @Override protected void onDestroy() { super.onDestroy(); destroyed = true; } private void preloadWeather() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); String lastToday = sp.getString("lastToday", ""); Log.e("226-LCL-", "lastToday = null ? " + lastToday.isEmpty()); if (!lastToday.isEmpty()) { Log.e("229-LCL-", "TodayWeatherTask."); new TodayWeatherTask().execute("cachedResponse", lastToday); } String lastLongterm = sp.getString("lastLongterm", ""); Log.e("233-LCL-", "lastLongterm = null?" + lastLongterm.isEmpty()); if (!lastLongterm.isEmpty()) { Log.e("235-LCL-", "LongTermWeatherTask."); new LongTermWeatherTask().execute("cachedResponse", lastLongterm); } } private void getTodayWeather() { Log.e("-LCL-", "getTodayWeather"); new TodayWeatherTask().execute(); } private void getLongTermWeather() { Log.e("-LCL-", "getLongTermWeather"); new LongTermWeatherTask().execute(); } private void searchCities() { AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle(this.getString(R.string.search_title)); final EditText input = new EditText(this); input.setInputType(InputType.TYPE_CLASS_TEXT); input.setMaxLines(1); input.setSingleLine(true); alert.setView(input, 32, 0, 32, 0); alert.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { String result = input.getText().toString(); if (!result.isEmpty()) { saveLocation(result); } } }); alert.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // Cancelled } }); alert.show(); } private void saveLocation(String result) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); recentCity = preferences.getString("city", Constants.DEFAULT_CITY); SharedPreferences.Editor editor = preferences.edit(); editor.putString("city", result); editor.commit(); getTodayWeather(); getLongTermWeather(); } private void aboutDialog() { AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("ThumbWeather"); final WebView webView = new WebView(this); String about = "<p>A light,open source App.</p>" + "<p>Data provided by <a href='http://openweathermap.org/'>OpenWeatherMap</a>, under the <a href='http://creativecommons.org/licenses/by-sa/2.0/'>Creative Commons license</a>" + "<p>Icons are <a href='https://erikflowers.github.io/weather-icons/'>Weather Icons</a>, by <a href='http://www.twitter.com/artill'>Lukas Bischoff</a> and <a href='http://www.twitter.com/Erik_UX'>Erik Flowers</a>, under the <a href='http://scripts.sil.org/OFL'>SIL OFL 1.1</a> licence."; if (darkTheme) { // Style text color for dark theme about = "<style media=\"screen\" type=\"text/css\">" + "body {\n" + " color:white;\n" + "}\n" + "a:link {color:cyan}\n" + "</style>" + about; } webView.setBackgroundColor(Color.TRANSPARENT); webView.loadData(about, "text/html", "UTF-8"); alert.setView(webView, 32, 0, 32, 0); alert.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); alert.show(); } // private String setWeatherIcon(int actualId, int hourOfDay) { int id = actualId / 100; String icon = ""; if (actualId == 800) { if (hourOfDay >= 7 && hourOfDay < 20) { icon = this.getString(R.string.weather_sunny); } else { icon = this.getString(R.string.weather_clear_night); } } else { switch (id) { case 2: icon = this.getString(R.string.weather_thunder); break; case 3: icon = this.getString(R.string.weather_drizzle); break; case 7: icon = this.getString(R.string.weather_foggy); break; case 8: icon = this.getString(R.string.weather_cloudy); break; case 6: icon = this.getString(R.string.weather_snowy); break; case 5: icon = this.getString(R.string.weather_rainy); break; } } return icon; } private String getRainString(JSONObject rainObj) { String rain = "0"; if (rainObj != null) { rain = rainObj.optString("3h", "fail"); if ("fail".equals(rain)) { rain = rainObj.optString("1h", "0"); } } return rain; } /** * Json?,???. * return?. * result,resultopenWeatherMapJson?. * @param * @return * * todayWeather?,??? */ private ParseResult parseTodayJson(String result) { Log.e("-LCL-", "---parseTodayJson---:result:" + result); try { //. JSONObject reader = new JSONObject(result); //???,?:CITY_NOT_FOUND. final String code = reader.optString("cod"); if ("404".equals(code)) { return ParseResult.CITY_NOT_FOUND; } todayWeather.setDate(reader.getString("dt")); //?,,???todayWeather. String city = reader.getString("name"); String country = ""; JSONObject countryObj = reader.optJSONObject("sys"); if (countryObj != null) { country = countryObj.getString("country"); todayWeather.setSunrise(countryObj.getString("sunrise")); todayWeather.setSunset(countryObj.getString("sunset")); } todayWeather.setCity(city); todayWeather.setCountry(country); JSONObject main = reader.getJSONObject("main"); todayWeather.setTemperature(main.getString("temp")); todayWeather.setDescription(reader.getJSONArray("weather").getJSONObject(0).getString("description")); JSONObject windObj = reader.getJSONObject("wind"); todayWeather.setWind(windObj.getString("speed")); if (windObj.has("deg")) { todayWeather.setWindDirectionDegree(windObj.getDouble("deg")); } else { Log.e("parseTodayJson", "No wind direction available"); todayWeather.setWindDirectionDegree(null); } todayWeather.setPressure(main.getString("pressure")); todayWeather.setHumidity(main.getString("humidity")); JSONObject rainObj = reader.optJSONObject("rain"); String rain; if (rainObj != null) { rain = getRainString(rainObj); } else { JSONObject snowObj = reader.optJSONObject("snow"); if (snowObj != null) { rain = getRainString(snowObj); } else { rain = "0"; } } //???,,??todayWeather. todayWeather.setRain(rain); final String idString = reader.getJSONArray("weather").getJSONObject(0).getString("id"); todayWeather.setId(idString); todayWeather.setIcon( setWeatherIcon(Integer.parseInt(idString), Calendar.getInstance().get(Calendar.HOUR_OF_DAY))); todayWeather.setTemp_max(main.getString("temp_max")); todayWeather.setTemp_min(main.getString("temp_min")); temperToday.add(mapTemper(todayWeather, 0)); //??SharedPreferences. SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainActivity.this) .edit(); editor.putString("lastToday", result); editor.commit(); } catch (JSONException e) { //?Json??,?:JSON_EXCEPTION. Log.e("-LCL--->JSONException", result); e.printStackTrace(); return ParseResult.JSON_EXCEPTION; } //???,?:OK. return ParseResult.OK; } private void updateTodayWeatherUI() { String city = todayWeather.getCity(); Log.d("402-LCL-", "updateTodayWeatherUI:city = " + city); String country = todayWeather.getCountry(); DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(getApplicationContext()); Log.d("402-LCL-", "cityIS:" + city + (country.isEmpty() ? "" : ", " + country)); cityIs.setText(city + (country.isEmpty() ? "" : ", " + country)); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); String temperature = todayWeather.getTemperature(); if (sp.getString("unit", "C").equals("C")) { temperature = Float.parseFloat(temperature) - 273.15 + ""; } if (sp.getString("unit", "C").equals("F")) { temperature = (((9 * (Float.parseFloat(temperature) - 273.15)) / 5) + 32) + ""; } double wind = Double.parseDouble(todayWeather.getWind()); if (sp.getString("speedUnit", "m/s").equals("kph")) { wind = wind * 3.59999999712; } if (sp.getString("speedUnit", "m/s").equals("mph")) { wind = wind * 2.23693629205; } double pressure = Double.parseDouble(todayWeather.getPressure()); if (sp.getString("pressureUnit", "hPa").equals("kPa")) { pressure = pressure / 10; } if (sp.getString("pressureUnit", "hPa").equals("mm Hg")) { pressure = pressure * 0.750061561303; } if (new BigDecimal(temperature).setScale(0, RoundingMode.DOWN).intValue() == 0) { temperature = "0"; } else { temperature = temperature.substring(0, temperature.indexOf(".") + 2); } todayTemperature.setText(temperature + " " + sp.getString("unit", "C")); if (todayWeather.getRain() != null) { if (Float.parseFloat(todayWeather.getRain()) > 0.1) { todayDescription.setText(todayWeather.getDescription().substring(0, 1).toUpperCase() + todayWeather.getDescription().substring(1) + " (" + todayWeather.getRain().substring(0, todayWeather.getRain().indexOf(".") + 2) + " mm)"); } else { todayDescription.setText(todayWeather.getDescription().substring(0, 1).toUpperCase() + todayWeather.getDescription().substring(1)); } todayWind.setText( getString(R.string.wind) + ": " + (wind + "").substring(0, (wind + "").indexOf(".") + 2) + " " + localize(sp, "speedUnit", "m/s") + (todayWeather.isWindDirectionAvailable() ? " " + getWindDirectionString(sp, this, todayWeather) : "")); todayPressure.setText(getString(R.string.pressure) + ": " + (pressure + "").substring(0, (pressure + "").indexOf(".") + 2) + " " + localize(sp, "pressureUnit", "hPa")); todayHumidity.setText(getString(R.string.humidity) + ": " + todayWeather.getHumidity() + " %"); todaySunrise.setText(getString(R.string.sunrise) + ": " + timeFormat.format(todayWeather.getSunrise())); todaySunset.setText(getString(R.string.sunset) + ": " + timeFormat.format(todayWeather.getSunset())); todayIcon.setText(todayWeather.getIcon()); } } public ParseResult parseLongTermJson(String result) { Log.e("522-LCL-", "---parseLongTermJson---:result:" + result); try { final Gson gson = new Gson(); javaBean javaben = gson.fromJson(result, javaBean.class); final String code = javaben.getCod(); if ("404".equals(code)) { return ParseResult.CITY_NOT_FOUND; } longTermWeather = new ArrayList<>(); longTermTodayWeather = new ArrayList<>(); longTermTomorrowWeather = new ArrayList<>(); longTemper = new ArrayList<>(); List<javaBean.ListEntity> listEntities = javaben.getList(); Log.e("-LCL-", "list.size():" + listEntities.size()); int today_time = 0; int tomorrow_time = 0; int later_time = 0; int later_time1 = 0; int later_time2 = 0; Log.e("525-LCL-", "listEntities.size():" + listEntities.size()); for (int i = 0; i < listEntities.size(); i++) { Log.e("f-LCL-", "i = " + i); Weather weather = new Weather(); javaBean.ListEntity list = listEntities.get(i); javaBean.ListEntity.MainEntity main = list.getMain(); weather.setDate(list.getDt() + ""); weather.setTemperature(main.getTemp() + ""); weather.setTemp_max(main.getTemp_max() + ""); weather.setTemp_min(main.getTemp_min() + ""); weather.setDescription(list.getWeather().get(0).getDescription()); if (list.getRain() == null) { weather.setRain(""); } else { weather.setRain(list.getRain().getThreeh() + ""); } weather.setWind(list.getWind().getSpeed()); weather.setWindDirectionDegree(list.getWind().getDeg()); weather.setPressure(main.getPressure() + ""); weather.setHumidity(main.getHumidity() + ""); javaBean.ListEntity.RainEntity rainEntity = list.getRain(); String rain = ""; if (rainEntity != null) { rain = rainEntity.getThreeh() + ""; } weather.setRain(rain); final String idString = list.getWeather().get(0).getId() + ""; weather.setId(idString); final String dateMsString = list.getDt() + "000"; Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(Long.parseLong(dateMsString)); weather.setIcon(setWeatherIcon(Integer.parseInt(idString), cal.get(Calendar.HOUR_OF_DAY))); Calendar today = Calendar.getInstance(); if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) { //today's all weather that reported per 3 hours. longTermTodayWeather.add(weather); temperToday.add(mapTemper(weather, today_time)); today_time++; } else if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR) + 1) { //tomorrow's all weather that reported per 3 hours. longTermTomorrowWeather.add(weather); temperTomorrow.add(mapTemper(weather, tomorrow_time)); tomorrow_time++; } else { //later's all weather that reported per 3 hours. longTermWeather.add(weather); if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR) + 2) { temperLater.add(mapTemper(weather, later_time)); later_time++; } else if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR) + 3) { temperLater1.add(mapTemper(weather, later_time1)); later_time1++; } else if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR) + 4) { temperLater2.add(mapTemper(weather, later_time2)); later_time2++; } } //add everyday's weather information into longTemper list. longTemper.add(weather); } Log.e("564-LCL", "today_time:" + today_time + ",tomorrow_time:" + tomorrow_time + ",later_time:" + later_time + ",later_time1:" + later_time1 + ",later_time2:" + later_time2); SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainActivity.this) .edit(); editor.putString("lastLongterm", result); editor.commit(); } catch (JsonSyntaxException e) { return ParseResult.JSON_EXCEPTION; } //add everyday's temper information into temperlist. temper = new ArrayList(); temper.add(temperToday); temper.add(temperTomorrow); temper.add(temperLater); temper.add(temperLater1); temper.add(temperLater2); Log.e("-LCL-", "longTermTodayWeather:" + longTermTodayWeather.size()); Log.e("-LCL-", "longTermTomorrowWeather:" + longTermTomorrowWeather.size()); Log.e("-LCL-", "longTermWeather:" + longTermWeather.size()); Log.e("-LCL-", "temper:" + temper.size()); return ParseResult.OK; } public Temper mapTemper(Weather weather, int day) { Temper temp = new Temper(); temp.setDay(day); temp.setHighTemper0(weather.getTemp_max()); temp.setLowTemper0(weather.getTemp_min()); return temp; } /** * ??? * */ private void updateLongTermWeatherUI() { if (destroyed) { return; } //ViewPagerAdapter ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager()); //?? Bundle bundleTemper = new Bundle(); bundleTemper.putInt("day", 3); bundleTemper.putParcelableArrayList("list", temper); TemperLineChartFragemnt temperLineChartFragemnt = new TemperLineChartFragemnt(this, todayWeather); temperLineChartFragemnt.setArguments(bundleTemper); viewPagerAdapter.addFragment(temperLineChartFragemnt, getString(R.string.temper)); //?? Bundle bundleToday = new Bundle(); bundleToday.putInt("day", 0); RecyclerViewFragment recyclerViewFragmentToday = new RecyclerViewFragment(); recyclerViewFragmentToday.setArguments(bundleToday); viewPagerAdapter.addFragment(recyclerViewFragmentToday, getString(R.string.today)); //?? Bundle bundleTomorrow = new Bundle(); bundleTomorrow.putInt("day", 1); RecyclerViewFragment recyclerViewFragmentTomorrow = new RecyclerViewFragment(); recyclerViewFragmentTomorrow.setArguments(bundleTomorrow); viewPagerAdapter.addFragment(recyclerViewFragmentTomorrow, getString(R.string.tomorrow)); //??? Bundle bundle = new Bundle(); bundle.putInt("day", 2); RecyclerViewFragment recyclerViewFragment = new RecyclerViewFragment(); recyclerViewFragment.setArguments(bundle); viewPagerAdapter.addFragment(recyclerViewFragment, getString(R.string.later)); int currentPage = viewPager.getCurrentItem(); //ViewPagerAdapter?ViewPager viewPagerAdapter.notifyDataSetChanged(); viewPager.setAdapter(viewPagerAdapter); tabLayout.setupWithViewPager(viewPager); if (currentPage == 0 && longTermTodayWeather.isEmpty()) { currentPage = 1; } viewPager.setCurrentItem(currentPage, false); } private boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_scrolling, menu); return true; } /** * * @param item * @return */ @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_refresh) { if (isNetworkAvailable()) { getTodayWeather(); getLongTermWeather(); } else { Snackbar.make(appView, getString(R.string.msg_connection_not_available), Snackbar.LENGTH_LONG) .show(); } return true; } if (id == R.id.action_search) { searchCities(); return true; } if (id == R.id.action_location) { getCityByLocation(); return true; } if (id == R.id.action_settings) { Intent intent = new Intent(MainActivity.this, SettingsActivity.class); startActivity(intent); } if (id == R.id.action_about) { aboutDialog(); return true; } if (id == R.id.action_share) { Intent intent = new Intent(MainActivity.this, SendMessageActivity.class); startActivity(intent); } return super.onOptionsItemSelected(item); } private void restorePreviousCity() { if (!TextUtils.isEmpty(recentCity)) { SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainActivity.this) .edit(); editor.putString("city", recentCity); editor.commit(); recentCity = ""; } } private void initMappings() { speedUnits.put("m/s", R.string.speed_unit_mps); speedUnits.put("kph", R.string.speed_unit_kph); speedUnits.put("mph", R.string.speed_unit_mph); pressUnits.put("hPa", R.string.pressure_unit_hpa); pressUnits.put("kPa", R.string.pressure_unit_kpa); pressUnits.put("mm Hg", R.string.pressure_unit_mmhg); } private String localize(SharedPreferences sp, String preferenceKey, String defaultValueKey) { return localize(sp, this, preferenceKey, defaultValueKey); } public static String localize(SharedPreferences sp, Context context, String preferenceKey, String defaultValueKey) { String preferenceValue = sp.getString(preferenceKey, defaultValueKey); String result = preferenceValue; if ("speedUnit".equals(preferenceKey)) { if (speedUnits.containsKey(preferenceValue)) { result = context.getString(speedUnits.get(preferenceValue)); } } else if ("pressureUnit".equals(preferenceKey)) { if (pressUnits.containsKey(preferenceValue)) { result = context.getString(pressUnits.get(preferenceValue)); } } return result; } public static String getWindDirectionString(SharedPreferences sp, Context context, Weather weather) { String pref = sp.getString("windDirectionFormat", null); if ("arrow".equals(pref)) { return weather.getWindDirection(8).getArrow(context); } else if ("abbr".equals(pref)) { return weather.getWindDirection().getLocalizedString(context); } return ""; } void getCityByLocation() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS)) { // Explanation not needed, since user requests this himself } else { ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, MY_PERMISSIONS_ACCESS_FINE_LOCATION); } } else { progressDialog.setMessage(getString(R.string.getting_location)); progressDialog.setCanceledOnTouchOutside(false); progressDialog.show(); LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_ACCESS_FINE_LOCATION: { // ?,0 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { getCityByLocation(); } return; } } } @Override public void onLocationChanged(Location location) { progressDialog.hide(); Log.i("GPS LOCATION", location.getLatitude() + ", " + location.getLongitude()); double latitude = location.getLatitude(); double longitude = location.getLongitude(); new ProvideCityNameTask().execute("coords", Double.toString(latitude), Double.toString(longitude)); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } abstract class GenericRequestTask extends AsyncTask<String, String, TaskOutput> { private void incLoadingCounter() { Log.e("897-LCL-", "incLoadingCounter:loading = " + loading); loading++; } private void decLoadingCounter() { Log.e("902-LCL-", "decLoadingCounter:loading = " + loading); loading--; } @Override protected void onPreExecute() { Log.e("908-LCL-", "GenericRequestTask:onPreExecute"); incLoadingCounter(); if (!progressDialog.isShowing()) { progressDialog.setMessage(getString(R.string.downloading_data)); progressDialog.setCanceledOnTouchOutside(false); progressDialog.show(); } } @Override protected TaskOutput doInBackground(String... params) { Log.e("794-LCL-", "doInBackground."); final TaskOutput output = new TaskOutput(); output.parseResult = null; output.taskResult = null; String response = ""; String[] coords = new String[] {}; if (params != null && params.length > 0) { final String zeroParam = params[0]; if ("cachedResponse".equals(zeroParam)) { response = params[1]; // ? output.taskResult = TaskResult.SUCCESS; } else if ("coords".equals(zeroParam)) { String lat = params[1]; String lon = params[2]; coords = new String[] { lat, lon }; } } if (response.isEmpty()) { Log.e("822-LCL-", "response.isEmpty():" + response.isEmpty()); try { //,? URL url = provideURL(coords); Log.e("947-LCL-", "URL = " + url.toString()); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); Log.e("925-LCL-", "urlConnection.getResponseCode() = " + urlConnection.getResponseCode()); int responseCode = urlConnection.getResponseCode(); if (responseCode == 200) { InputStreamReader inputStreamReader = new InputStreamReader(urlConnection.getInputStream()); BufferedReader r = new BufferedReader(inputStreamReader); String line = null; while ((line = r.readLine()) != null) { response += line + "\n"; } close(r); urlConnection.disconnect(); // if (response.contains("<html>")) { Log.e("947-LCL-", "TaskResult.BAD_RESPONSE"); output.taskResult = TaskResult.BAD_RESPONSE; } else { Log.e("Task", "done successfully:response = " + response); output.taskResult = TaskResult.SUCCESS; } } else if (responseCode == 429) { // Log.e("Task", "too many requests"); output.taskResult = TaskResult.TOO_MANY_REQUESTS; } else { // ?? Log.e("Task", "bad response"); output.taskResult = TaskResult.BAD_RESPONSE; } } catch (IOException e) { Log.e("IOException Data", response); e.printStackTrace(); // ???IO output.taskResult = TaskResult.IO_EXCEPTION; } } if (TaskResult.SUCCESS.equals(output.taskResult)) { // ?JSON? ParseResult parseResult = parseResponse(response); Log.e("850-LCL-", "success-->response:" + response); if (ParseResult.CITY_NOT_FOUND.equals(parseResult)) { //??,? restorePreviousCity(); } output.parseResult = parseResult; } Log.e("857-LCL-", "parseResult:" + output.parseResult); return output; } @Override protected void onPostExecute(TaskOutput output) { Log.e("1015-LCL-", "onPostExecute"); if (loading == 1) { progressDialog.dismiss(); } decLoadingCounter(); handleTaskOutput(output); } protected final void handleTaskOutput(TaskOutput output) { Log.e("1025-LCL-", "handleTaskOutput:TaskOutput = " + output.taskResult); switch (output.taskResult) { case SUCCESS: { ParseResult parseResult = output.parseResult; if (ParseResult.CITY_NOT_FOUND.equals(parseResult)) { Snackbar.make(appView, getString(R.string.msg_city_not_found), Snackbar.LENGTH_LONG).show(); } else if (ParseResult.JSON_EXCEPTION.equals(parseResult)) { Snackbar.make(appView, getString(R.string.msg_err_parsing_json), Snackbar.LENGTH_LONG).show(); } else { updateMainUI(); } break; } case TOO_MANY_REQUESTS: { Snackbar.make(appView, getString(R.string.msg_too_many_requests), Snackbar.LENGTH_LONG).show(); break; } case BAD_RESPONSE: { Snackbar.make(appView, getString(R.string.msg_connection_problem), Snackbar.LENGTH_LONG).show(); break; } case IO_EXCEPTION: { Snackbar.make(appView, getString(R.string.msg_connection_not_available), Snackbar.LENGTH_LONG) .show(); break; } } } private String getLanguage() { String language = Locale.getDefault().getLanguage(); if (language.equals("cs")) { language = "cz"; } return language; } private URL provideURL(String[] coords) throws UnsupportedEncodingException, MalformedURLException { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); final String apiKey = sp.getString("apiKey", getResources().getString(R.string.apiKey)); StringBuilder urlBuilder = new StringBuilder("http://api.openweathermap.org/data/2.5/"); urlBuilder.append(getAPIName()).append("?"); if (coords.length == 2) { urlBuilder.append("lat=").append(coords[0]).append("&lon=").append(coords[1]); } else { final String city = sp.getString("city", Constants.DEFAULT_CITY); urlBuilder.append("q=").append(URLEncoder.encode(city, "UTF-8")); } urlBuilder.append("&lang=").append(getLanguage()); urlBuilder.append("&mode=json"); urlBuilder.append("&appid=").append(apiKey); Log.e("-LCL-", "doInBackground:URI:" + urlBuilder.toString()); return new URL(urlBuilder.toString()); } protected void updateMainUI() { } protected abstract ParseResult parseResponse(String response); protected abstract String getAPIName(); } class TodayWeatherTask extends GenericRequestTask { @Override protected void onPreExecute() { Log.e("-LCL-", "TodayWeatherTask:onPreExecute"); loading = 0; super.onPreExecute(); } @Override protected ParseResult parseResponse(String response) { Log.e("-LCL-", "TodayWeatherTask:parseResponse"); return parseTodayJson(response); } @Override protected String getAPIName() { return "weather"; } @Override protected void updateMainUI() { Log.e("-LCL-", "updateMainUI:updateTodayWeatherUI"); updateTodayWeatherUI(); } } class LongTermWeatherTask extends GenericRequestTask { @Override protected ParseResult parseResponse(String response) { Log.e("1083-LCL-", "LongTermWeatherTask:parseResponse = " + response); return parseLongTermJson(response); } @Override protected String getAPIName() { return "forecast"; } @Override protected void updateMainUI() { Log.e("1010-LCL-", "updateMainUI:updateLongTermWeatherUI"); updateLongTermWeatherUI(); } } class ProvideCityNameTask extends GenericRequestTask { @Override protected void onPreExecute() { /*Nothing*/ } @Override protected String getAPIName() { return "weather"; } @Override protected ParseResult parseResponse(String response) { Log.i("993-LCL-.RESULT", response.toString()); if (!response.isEmpty()) { final Gson gson = new Gson(); javaBean javabean = gson.fromJson(response, javaBean.class); final String code = javabean.getCod(); if ("404".equals(code)) { Log.e("Geolocation", "No city found"); return ParseResult.CITY_NOT_FOUND; } javaBean.CityEntity cityEntity = javabean.getCity(); String city = cityEntity.getName(); String country = ""; country = cityEntity.getCountry(); saveLocation(city + country); } else { Log.e("JSONException Data", response); return ParseResult.JSON_EXCEPTION; } return ParseResult.OK; } @Override protected void onPostExecute(TaskOutput output) { /* ??*/ handleTaskOutput(output); } } private class TaskOutput { /** * ?? */ ParseResult parseResult; /** * ? */ TaskResult taskResult; } private enum ParseResult { OK, JSON_EXCEPTION, CITY_NOT_FOUND } private enum TaskResult { SUCCESS, BAD_RESPONSE, IO_EXCEPTION, TOO_MANY_REQUESTS; } }