Skip to content

Instantly share code, notes, and snippets.

@InfoSec812
Last active December 18, 2015 21:59
Show Gist options
  • Save InfoSec812/5851358 to your computer and use it in GitHub Desktop.
Save InfoSec812/5851358 to your computer and use it in GitHub Desktop.
Several snippets which can be used to build a basic Android application.
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) ;
}
// 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....
}
// 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);
}
}
// 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) {
}
} ;
}
// 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) ;
}
// 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) ;
}
}
}
<!-- Create a refresh menu item -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/refresh"
android:title="@string/refresh_button_label"
android:orderInCategory="100"
android:showAsAction="ifRoom"
android:icon="@android:drawable/ic_popup_sync"/>
</menu>
// 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);
}
// 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