Last active
December 18, 2015 21:59
-
-
Save InfoSec812/5851358 to your computer and use it in GitHub Desktop.
Several snippets which can be used to build a basic Android application.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MainActivity extends Activity { | |
protected static final String TAG = "MainActivity" ; | |
// Define protected instances of the needed UI elements | |
protected ProgressBar busyIndicator = null ; | |
protected TextView weatherData = null ; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
// Use the View.findViewById() method to assign those UI elements to our protected instances | |
busyIndicator = (ProgressBar) findViewById(R.id.loadingIndicator); | |
weatherData = (TextView) findViewById(R.id.weatherInformation) ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Stub in 2 methods. doLocation for handling location lookup and doWeather for handling the Weather lookup. | |
/** | |
* Using the {@link android.location.LocationManager}, implement a {@link android.location.LocationListener} which will | |
* get the user's current location and kick off a background task to update the weather information | |
* using a ReSTful call to an external service | |
*/ | |
protected void doLocation() { | |
// TODO: Implement Location resolution and then pass that to doWeather(Location) | |
} | |
/** | |
* Given a {@link android.location.Location}, call an {@link android.os.AsyncTask} to perform a ReSTful | |
* request to get the weather for the corresponding lat/long. | |
* @param location A {@link Location} object containing lat/long and various other data which describes the current location | |
*/ | |
protected void doWeather(Location location) { | |
// TODO: Implement weather ReST request processing.... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Stub in an implementation of AsyncTask to handle performing the ReSTful requests in the background. | |
protected class WeatherUpdater extends AsyncTask<Location, Void, Weather> { | |
@Override | |
protected Weather doInBackground(Location... locations) { | |
return null; | |
} | |
@Override | |
protected void onPostExecute(Weather weather) { | |
super.onPostExecute(weather); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Get a reference to the LocationManager/Service and stub in an implementation of the LocationListener interface | |
/** | |
* Using the {@link android.location.LocationManager}, implement a {@link android.location.LocationListener} which will | |
* get the user's current location and kick off a background task to update the weather information | |
* using a ReSTful call to an external service | |
*/ | |
protected void doLocation() { | |
busyIndicator.setVisibility(View.VISIBLE) ; | |
locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE) ; | |
locationListener = new LocationListener() { | |
@Override | |
public void onLocationChanged(Location location) { | |
} | |
@Override | |
public void onStatusChanged(String s, int i, Bundle bundle) { | |
} | |
@Override | |
public void onProviderEnabled(String s) { | |
} | |
@Override | |
public void onProviderDisabled(String s) { | |
} | |
} ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill in the logic for the LocationListener | |
protected LocationManager locationManager = null ; | |
protected LocationListener locationListener = null ; | |
/** | |
* Using the {@link android.location.LocationManager}, implement a {@link android.location.LocationListener} which will | |
* get the user's current location and kick off a background task to update the weather information | |
* using a ReSTful call to an external service | |
*/ | |
protected void doLocation() { | |
busyIndicator.setVisibility(View.VISIBLE) ; | |
locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE) ; | |
// Create an anonymous inner class to handle location callbacks | |
locationListener = new LocationListener() { | |
Location lastLocation = null ; | |
@Override | |
public void onLocationChanged(Location location) { | |
Log.d(TAG, "Got new location data.") ; | |
if (lastLocation!=null) { | |
if (isBetterLocation(location, lastLocation)) { | |
// We got a location from the location provider, send that to the doWeather() method to do the ReST request. | |
ConnectivityManager connMgr = (ConnectivityManager) | |
getSystemService(CONNECTIVITY_SERVICE); | |
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); | |
if (networkInfo != null && networkInfo.isConnected()) { | |
// Internet connectivity WAS detected, proceed | |
Log.i(TAG, "Handling new location data") ; | |
MainActivity.this.doWeather(location) ; | |
} else { | |
// No Internet connection was detected, alert the user to try again later. | |
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this) ; | |
builder.setTitle(R.string.no_network_dialog_title) ; | |
builder.setMessage(R.string.no_network_dialog_message) ; | |
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialogInterface, int i) { | |
dialogInterface.dismiss() ; | |
} | |
}) ; | |
builder.show() ; | |
} | |
} | |
} else { | |
if (location.getAccuracy()>40) { | |
Log.i(TAG, "Handling new location data") ; | |
MainActivity.this.doWeather(location) ; | |
} | |
} | |
lastLocation = location ; | |
} | |
@Override | |
public void onStatusChanged(String s, int i, Bundle bundle) { | |
} | |
@Override | |
public void onProviderEnabled(String s) { | |
} | |
@Override | |
public void onProviderDisabled(String s) { | |
} | |
private static final int TWO_MINUTES = 1000 * 60 * 2; | |
/** Determines whether one Location reading is better than the current Location fix | |
* @param location The new Location that you want to evaluate | |
* @param currentBestLocation The current Location fix, to which you want to compare the new one | |
* #Copyright Google Inc. - Taken from developer.android.com | |
*/ | |
protected boolean isBetterLocation(Location location, Location currentBestLocation) { | |
if (currentBestLocation == null) { | |
// A new location is always better than no location | |
return true; | |
} | |
// Check whether the new location fix is newer or older | |
long timeDelta = location.getTime() - currentBestLocation.getTime(); | |
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; | |
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; | |
boolean isNewer = timeDelta > 0; | |
// If it's been more than two minutes since the current location, use the new location | |
// because the user has likely moved | |
if (isSignificantlyNewer) { | |
return true; | |
// If the new location is more than two minutes older, it must be worse | |
} else if (isSignificantlyOlder) { | |
return false; | |
} | |
// Check whether the new location fix is more or less accurate | |
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); | |
boolean isLessAccurate = accuracyDelta > 0; | |
boolean isMoreAccurate = accuracyDelta < 0; | |
boolean isSignificantlyLessAccurate = accuracyDelta > 200; | |
// Check if the old and new location are from the same provider | |
boolean isFromSameProvider = isSameProvider(location.getProvider(), | |
currentBestLocation.getProvider()); | |
// Determine location quality using a combination of timeliness and accuracy | |
if (isMoreAccurate) { | |
return true; | |
} else if (isNewer && !isLessAccurate) { | |
return true; | |
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { | |
return true; | |
} | |
return false; | |
} | |
/** Checks whether two providers are the same */ | |
private boolean isSameProvider(String provider1, String provider2) { | |
if (provider1 == null) { | |
return provider2 == null; | |
} | |
return provider1.equals(provider2); | |
} | |
}; | |
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener) ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill in the logic for the WeatherUpdater AsyncTask | |
protected class WeatherUpdater extends AsyncTask<Location, Void, Weather> { | |
private String readIt(InputStream stream) throws IOException, UnsupportedEncodingException { | |
Reader reader = null; | |
reader = new InputStreamReader(stream, "UTF-8"); | |
char[] buffer = new char[1024]; | |
StringBuilder sb = new StringBuilder() ; | |
// reader.read() returns -1 at EOF | |
while (reader.read(buffer)>0) { | |
sb.append(new String(buffer)) ; | |
} | |
return sb.toString() ; | |
} | |
@Override | |
protected Weather doInBackground(Location... locations) { | |
// Everything in this method is run in a background thread and not in the UI thread | |
String apiURL = "http://api.wunderground.com/api/d82adbd526135f93/conditions/q/"+locations[0].getLatitude()+","+locations[0].getLongitude()+".json" ; | |
InputStream is = null ; | |
Log.d(TAG, "Preparing to send ReSTful request.") ; | |
try { | |
URL url = new URL(apiURL); | |
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); | |
conn.setReadTimeout(10000 /* milliseconds */); | |
conn.setConnectTimeout(15000 /* milliseconds */); | |
conn.setRequestMethod("GET"); | |
conn.setDoInput(true); | |
// Starts the query | |
conn.connect(); | |
int response = conn.getResponseCode(); | |
Log.d(TAG, "The response is: " + response); | |
is = conn.getInputStream(); | |
// Convert the InputStream into a string | |
String contentAsString = readIt(is); | |
// Parse string as JSON | |
JSONObject json = new JSONObject(contentAsString) ; | |
JSONObject curr = json.getJSONObject("current_observation") ; | |
Weather current = new Weather() ; | |
current.setLocationName(curr.getJSONObject("display_location").getString("full")); | |
current.setDescription(curr.getString("weather")); | |
current.setTempFarenheit(curr.getDouble("temp_f")); | |
current.setHumidity(curr.getString("relative_humidity")); | |
current.setVisibilityMiles(curr.getString("visibility_mi")); | |
current.setWindDirection(curr.getString("wind_dir")); | |
current.setWindSpeedMph(curr.getLong("wind_mph")); | |
return current ; | |
// Makes sure that the InputStream is closed after the app is | |
// finished using it. | |
} catch (IOException ioe) { | |
Log.e(TAG, ioe.getLocalizedMessage(), ioe) ; | |
} catch (JSONException jsonE) { | |
Log.e(TAG, jsonE.getLocalizedMessage(), jsonE) ; | |
} finally { | |
if (is != null) { | |
try { | |
is.close(); | |
} catch (Exception e) { | |
Log.e(TAG, e.getLocalizedMessage(), e) ; | |
} | |
} | |
is = null ; | |
} | |
return null; | |
} | |
@Override | |
protected void onPreExecute() { | |
Log.d(TAG, "PreExecute") ; | |
super.onPreExecute(); | |
if (busyIndicator!=null) { | |
busyIndicator.setVisibility(View.VISIBLE) ; | |
} | |
} | |
@Override | |
protected void onPostExecute(Weather s) { | |
super.onPostExecute(s); | |
// TODO: Add logic to update the UI with the weather data | |
StringBuilder sb = new StringBuilder() ; | |
sb.append("Weather for: "+s.getLocationName()+"\n") ; | |
sb.append("Temperature: "+s.getTempFarenheit()+"\n") ; | |
sb.append("Description: "+s.getDescription()+"\n") ; | |
sb.append("Wind Direction: "+s.getWindDirection()+"\n") ; | |
sb.append("Wind Speed: "+s.getWindSpeedMph()+"\n") ; | |
sb.append("Humidity: "+s.getHumidity()+"\n") ; | |
weatherData.setText(sb.toString()) ; | |
if (busyIndicator!=null) { | |
busyIndicator.setVisibility(View.GONE) ; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Implement the main menu using the menuInflater | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
// Inflate the menu; this adds items to the action bar if it is present. | |
getMenuInflater().inflate(R.menu.main, menu); | |
return true; | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
Log.d(TAG, "Menu item selected: "+item.getItemId()) ; | |
switch (item.getItemId()) { | |
case R.id.refresh: { | |
doLocation() ; | |
} | |
default: { | |
// NO OP | |
} | |
} | |
return super.onOptionsItemSelected(item); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create a Bean to hold the weather information which we will pass back. | |
package juggle.myweatherapp; | |
/** | |
* Created by dphillips on 6/20/13. | |
*/ | |
public class Weather { | |
private double temp_f ; | |
private String description ; | |
private String humidity ; | |
private String windDirection ; | |
private long windSpeedMph ; | |
private String visibilityMiles ; | |
private String locationName ; | |
public String getLocationName() { | |
return locationName ; | |
} | |
public void setLocationName(String name) { | |
this.locationName = name ; | |
} | |
public double getTempFarenheit() { | |
return temp_f; | |
} | |
public void setTempFarenheit(double temp_f) { | |
this.temp_f = temp_f; | |
} | |
public String getDescription() { | |
return description; | |
} | |
public void setDescription(String description) { | |
this.description = description; | |
} | |
public String getHumidity() { | |
return humidity; | |
} | |
public void setHumidity(String humidity) { | |
this.humidity = humidity; | |
} | |
public String getWindDirection() { | |
return windDirection; | |
} | |
public void setWindDirection(String windDirection) { | |
this.windDirection = windDirection; | |
} | |
public long getWindSpeedMph() { | |
return windSpeedMph; | |
} | |
public void setWindSpeedMph(long windSpeedMph) { | |
this.windSpeedMph = windSpeedMph; | |
} | |
public String getVisibilityMiles() { | |
return visibilityMiles; | |
} | |
public void setVisibilityMiles(String visibilityMiles) { | |
this.visibilityMiles = visibilityMiles; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment